为什么我的正则表达式包含'\ r'时工作速度很慢

时间:2014-05-20 13:44:41

标签: c# html regex

我只想尝试将某个html中的标头标签替换为另一个字符串。 我的HTML看起来像这样:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"><head><title>aboutus</title> 

    <header id="headerfasdfasdfasdf">
       <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer pulvinar commodo lorem, sit amet malesuada.</p>
    </header>

<!-- #include virtual="/html/US/global_header.html" --><script type="text/javascript">

   var header = document.getElementsByTagName("header");

    var len = header.length

    if(len > 1)

    {

    header[0].style.display = "none";

    }
</script>

    <!--ls:begin[component-1400226725207]-->

    <!-- OTHER PART IS CUT FOR BREVITY -->

</html>

我尝试使用正则表达式<header(.|\n|\r)*<\/header>对其进行解析,但在我删除|\r部分之前,它的工作速度非常慢。

此外,我注意到原始正则表达式适用于不包含<!--ls:begin[component-1400226725207]-->等注释的html。

请注意,我使用带有C#的.NET正则表达式引擎,我的替换代码如下所示:

var regex = @"<header(.|\n|\r)*<\/header>";
var result = Regex.Replace(input, regex, to, RegexOptions.IgnoreCase);

请帮助我理解为什么我会遇到这个问题。

2 个答案:

答案 0 :(得分:1)

如果您的输入被很好地消毒(即如果您感觉自己can use regex to parse HTML),这可能会显着提高您的速度:

var regex = @"<header.*?</header>";
var result = Regex.Replace(input, regex, to, RegexOptions.IgnoreCase|RegexOptions.Singleline);
  • 完全避免使用.|\n|\r,这是你想要做的事情的标志。
  • 使您的量词懒惰*?,因为标题标记可能不占用HTML的三分之二

当从文件末尾回溯到</header>时,(.|\n|\r)*的贪婪使得正则表达式引擎会在尝试</header>之前检查交替的每个元素。您添加到轮换中的任何元素都可能会带来更多的工作。

答案 1 :(得分:-1)

就个人而言,我会使用一个更简单的表达并告诉它。 (点)也匹配换行符: -

(?s)(?U)<header.*\/header>

(?s)表示匹配换行符以及其他字符。 (点)
(?U)表示匹配尽可能少的字符