这是一个奇怪的.NET正则表达式问题,我无法弄清楚。我试图在我的论坛应用中解析一些HTML。我还没有改变代码,但在某些环境中,正则表达式根本就不会返回。我可以在应用程序中重现它:
第66行:https://github.com/POPWorldMedia/POPForums/blob/master/PopForums/Services/TextParsingService.cs
text = Regex.Replace(text, @"(<iframe )(\S+ )*(src=""http://www.youtube.com/embed/)(\S+)("")( *\S+)*( */iframe>)", "http://www.youtube.com/watch?v=$4", RegexOptions.IgnoreCase);
它窒息的输入字符串是:
<p>This is an <strong>important</strong> <em>preview</em> of a post.</p>[quote]<p>This is a quote.<br /></p>[/quote]<p><iframe width="640" height="360" src="http://www.youtube.com/embed/Zey3WWThErw" frameborder="0" allowfullscreen></iframe></p><p>O look! YouTube!</p>
最终会在这里超时: http://regexlib.com/RETester.aspx
主机进程,在这种情况下,IIS在本地大约50%(一个核心,我假设),永远不会放弃或返回。我完全难过了。我在Azure上的一个网站上运行相同的代码并且它并没有在那里窒息。
答案 0 :(得分:3)
(\S+ )*
和( *\S+)*
部分导致批次回溯。
考虑简单地用.*
替换它们。它不是100%相当,但我认为它应该与我想要做的事情一起工作。
text = Regex.Replace(text, @"(<iframe )(.)*(src=""http://www.youtube.com/embed/)(\S+)("")(.)*( */iframe>)", "http://www.youtube.com/watch?v=$4", RegexOptions.IgnoreCase);
你的正则表达式会有其他问题,因为它贪婪地发挥作用。如果您的文字中有多个iframe
标记,则可能需要尝试此操作以确保没有任何问题。
text = Regex.Replace(text, @"(<iframe )(.)*?(src=""http://www.youtube.com/embed/)(\S+)("")(.)*?( */iframe>)", "http://www.youtube.com/watch?v=$4", RegexOptions.IgnoreCase);
与往常一样,您还应考虑使用HTML解析器而不是正则表达式来执行此类任务。
答案 1 :(得分:1)
唯一的问题是( \ * \S+ )*
。
发动机特别恼火混合(零/多*
与许多+
)* inside a zero/many group
。
在这种情况下,将许多人单一化,问题就解决了。即:( _* _+)*
至=&gt; ( _* _)*
这些是导致问题的唯一地方 ,尤其是当许多人可以匹配很多时
不同的人物。
总是先检查一下,不要对回溯感到偏执。
# @"(<iframe\ )(\S+\ )*(src=""http://www\.youtube\.com/embed/)(\S+)("")(\ *\S)*(\ */iframe>)"
( <iframe\ ) # (1)
( \S+ \ )* # (2)
( # (3 start)
src="http://www \. youtube \. com/embed/
) # (3 end)
( \S+ ) # (4)
( " ) # (5)
( \ * \S )* # (6)
( \ */iframe> ) # (7)
输出:
** Grp 0 - ( pos 119 , len 121 )
<iframe width="640" height="360" src="http://www.youtube.com/embed/Zey3WWThErw" frameborder="0" allowfullscreen></iframe>
** Grp 1 - ( pos 119 , len 8 )
<iframe
** Grp 2 - ( pos 139 , len 13 )
height="360"
** Grp 3 - ( pos 152 , len 34 )
src="http://www.youtube.com/embed/
** Grp 4 - ( pos 186 , len 11 )
Zey3WWThErw
** Grp 5 - ( pos 197 , len 1 )
"
** Grp 6 - ( pos 231 , len 1 )
<
** Grp 7 - ( pos 232 , len 8 )
/iframe>