Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用大型文档时,正则表达式运行速度非常慢_C#_Regex_Performance - Fatal编程技术网

C# 使用大型文档时,正则表达式运行速度非常慢

C# 使用大型文档时,正则表达式运行速度非常慢,c#,regex,performance,C#,Regex,Performance,我需要将内联css样式属性转换为它们的HTML标记等价物。我的解决方案可以工作,但使用Microsoft.Net正则表达式名称空间和长文档(约40页html)运行速度非常慢。我尝试了几种不同的方法,但没有任何有用的结果。我对表达式的执行做了一些包装,但最终只调用了内置的regexreplace方法 我肯定我滥用了正则表达式的贪婪性,但我不确定用一个正则表达式来实现我想要的 我希望能够运行以下单元测试: [Test] public void TestCleanReplacesFontWeightW

我需要将内联css样式属性转换为它们的HTML标记等价物。我的解决方案可以工作,但使用Microsoft.Net正则表达式名称空间和长文档(约40页html)运行速度非常慢。我尝试了几种不同的方法,但没有任何有用的结果。我对表达式的执行做了一些包装,但最终只调用了内置的regexreplace方法

我肯定我滥用了正则表达式的贪婪性,但我不确定用一个正则表达式来实现我想要的

我希望能够运行以下单元测试:

[Test]
public void TestCleanReplacesFontWeightWithB()
{
    string html = "<font style=\"font-weight:bold\">Bold Text</font>";
    html = Q4.PrWorkflow.Helper.CleanFormatting(html);
    Assert.AreEqual("<b>Bold Text</b>", html);
}
[Test]
public void TestCleanReplacesMultipleAttributesFontWeightWithB()
{
    string html = "<font style=\"font-weight:bold; color: blue; \">Bold Text</font>";
    html = Q4.PrWorkflow.Helper.CleanFormatting(html);
    Assert.AreEqual("<b>Bold Text</b>", html);
}
[Test]
public void TestCleanReplaceAttributesBoldAndUnderlineWithHtml()
{
    string html = "<span style=\"font-weight:bold; color: blue; text-decoration: underline; \">Bold Text</span>";
    html = Q4.PrWorkflow.Helper.CleanFormatting(html);
    Assert.AreEqual("<u><b>Bold Text</b></u>", html);
}
[Test]
public void TestCleanReplaceAttributesBoldUnderlineAndItalicWithHtml()
{
    string html = "<span style=\"font-weight:bold; color: blue; font-style: italic; text-decoration: underline; \">Bold Text</span>";
    html = Q4.PrWorkflow.Helper.CleanFormatting(html);
    Assert.AreEqual("<u><b><i>Bold Text</i></b></u>", html);
}
[Test]
public void TestCleanReplacesFontWeightWithSpaceWithB()
{
    string html = "<font size=\"10\" style=\"font-weight: bold\">Bold Text</font>";
    html = Q4.PrWorkflow.Helper.CleanFormatting(html);
    Assert.AreEqual("<b>Bold Text</b>", html);
}
[测试]
public void testcleansreplacesfontwortweightwithb()
{
字符串html=“粗体文本”;
html=Q4.PrWorkflow.Helper.CleanFormatting(html);
AreEqual(“粗体文本”,html);
}
[测试]
public void TestCleanReplacesMultipleAttributesFontWeightWithB()
{
字符串html=“粗体文本”;
html=Q4.PrWorkflow.Helper.CleanFormatting(html);
AreEqual(“粗体文本”,html);
}
[测试]
public void TestCleanReplaceAttributesBoldAndUnderlineWithHtml()的
{
字符串html=“粗体文本”;
html=Q4.PrWorkflow.Helper.CleanFormatting(html);
AreEqual(“粗体文本”,html);
}
[测试]
public void TestCleanReplaceAttributesBoldUnderlineAndAlicWithHTML()
{
字符串html=“粗体文本”;
html=Q4.PrWorkflow.Helper.CleanFormatting(html);
AreEqual(“粗体文本”,html);
}
[测试]
public void TestCleanSReplacesFontWeights with spaceWithB()
{
字符串html=“粗体文本”;
html=Q4.PrWorkflow.Helper.CleanFormatting(html);
AreEqual(“粗体文本”,html);
}
我用来实现这个逻辑的常规表达式可以工作,但速度非常慢。c代码中的正则表达式如下所示:

public static IReplacePattern IncludeInlineItalicToITag(ICleanUpHtmlFactory factory)
{
    return factory.CreateReplacePattern("(<(span|font) .*?style=\".*?font-style:\\s*italic[^>]*>)(.*?)</\\2>", "$1<i>$3</i></$2>");
}
public static IReplacePattern IncludeInlineBoldToBTag(ICleanUpHtmlFactory factory)
{
    return factory.CreateReplacePattern("(<(span|font) .*?style=\".*?font-weight:\\s*bold[^>]*>)(.*?)</\\2>", "$1<b>$3</b></$2>");
}
public static IReplacePattern IncludeInlineUnderlineToUTag(ICleanUpHtmlFactory factory)
{
    return factory.CreateReplacePattern("(<(span|font) .*?style=\".*?text-decoration:\\s*underline[^>]*>)(.*?)</\\2>", "$1<u>$3</u></$2>");
}
公共静态IReplacePattern,包括InLineItalicToItag(iClinuphtMLFactory工厂)
{
返回factory.CreateReplacePattern(“(]*>)(.*?”,“$1$3”);
}
公共静态IReplacePattern,包括InLineUnderlineToutag(iCaluphtmFactory工厂)
{

return factory.CreateReplacePattern((我认为问题在于,如果它找到一个
span
|
font
标记,它没有定义任何样式属性,它将继续查找它,直到文档结束,因为
\*?
。我没有测试它,但将它更改为
[^>]\*?
可能会提高性能

请确保对所有的
\*?
应用该更改;即使是捕获标记之间内容的更改(使用
[^).NET正则表达式不支持递归构造。PCRE支持,但这在这里并不重要

礼宾员

<font style="font-weight: bold;"> text1 <font color="blue"> text2 </font> text3 </font>
text1 text2 text3
它会被转换成

<b> text1 <font color="blue"> text2 </b> text3 </font>
text1 text2 text3
我的建议是使用适当的标记解析器,并可能对样式标记的值使用regexp

Edit:从头开始。似乎.NET有一个平衡的递归模式的结构。但没有PCRE/perl中的功能强大

(?<N>content) would push N onto a stack if content matches
(?<-N>content) would pop N from the stack, if content matches.
(?(N)yes|no) would match "yes" if N is on the stack, otherwise "no".
(?content)将在内容匹配时将N推到堆栈上
如果内容匹配,(?内容)将从堆栈中弹出N。
(?(N)yes | no)如果N在堆栈上,则匹配“yes”,否则匹配“no”。

详细信息请参见。

胡乱猜测:我相信成本来自备选方案和相应的匹配。 您可能要尝试替换:

"(<(span|font) .*?style=\".*?font-style:\\s*italic[^>]*>)(.*?)</\\2>", "$1<i>$3</i></$2>"
“(]*>)(.*?”,“$1$2”

(在测试过程中,我发现了奇怪的行为。当在单独的线程中运行regexp时,它会运行得更快。 我有一个sql脚本,我正在使用regexp将它从Go-to-Go拆分为多个部分。
在不使用单独线程的情况下处理此脚本时,它会持续大约2分钟。但在使用多线程时,它只会持续几秒钟。

同意。任何时候您都可以尝试改进正则表达式(无论是为了性能、清晰度还是其他方面),.*是您应该首先查看并尝试消除的内容。我完全同意。我部分继承了更新此代码的内容,因此我尝试使用使用正则表达式的相同模式进行更新-否则我可能不会使用纯正则表达式。在网络中完全可以处理此问题。请参阅正则表达式中的平衡组,它允许您使用例如,在我提供答案之前,我要问:您使用的是什么版本的.NET framework?如果您当前没有使用.NET 3.5,是否值得升级以获得它?
"(<span .*?style=\".*?font-style:\\s*italic[^>]*>)(.*?)</span>", "$1<i>$2</i></span>"
"(<font .*?style=\".*?font-style:\\s*italic[^>]*>)(.*?)</font>", "$1<i>$2</i></font>"