[英]RegExp exercise: reluctant quantifier with a lookahead assertion
你能解释一下这是怎么回事吗? 这是一个例子:
<!-- The quick brown fox
jumps over the lazy dog -->
<!--[if IE 7]>
<link rel="stylesheet" type="text/css" href="/supersheet.css" />
<![endif]-->
<!-- Pack my box with five dozen liquor jugs -->
首先,我尝试使用以下正则表达式来匹配条件注释中的内容:
/<!--.*?stylesheet.*?-->/s
它失败了,因为正则表达式匹配第一个<!--
和最后一个-->
之前的所有内容。 然后我尝试使用另一种模式与前瞻断言:
/<!--(?=.*?stylesheet).*?-->/s
它的工作原理与我需要的完全匹配。 但是,以下正则表达式也起作用:
/<!--(?=.*stylesheet).*?-->/s
最后一个正则表达式在前瞻断言中没有一个不情愿的量词。 现在我很困惑。 谁能解释一下它是如何工作的? 也许这个例子有更好的解决方案?
更新:
我尝试在另一个文档中使用lookahead断言来使用正则表达式,并且它无法在注释之间添加内容。 所以,这个/ / /<!--(?=.*?stylesheet).*?-->/s
(?=。*? /<!--(?=.*?stylesheet).*?-->/s
(以及这一个/ /<!--(?=.*?stylesheet).*?-->/s
(? /<!--(?=.*stylesheet).*?-->/s
)不正确。 不要使用它并尝试其他建议。
更新:
Jonny 5找到了解决方案(见答案)。 他提出了三种选择:
/style-sheet.css
,则它将不起作用。 \\K
它就像一个魅力。 缺点如下:
我认为以下是我的例子的一个很好的解决方案:
/(?s)<!--(?:(?!<!).)+?stylesheet.+?-->/
相同但最后使用s
修饰符:
/<!--(?:(?!<!).)+?stylesheet.+?-->/s
正如我所说,这是一个很好的解决方案,但我设法改进了模式,并找到了另一个在我的情况下工作得更快的模式。
所以,最终的解决方案如下:
/<!--(?:(?!-->).)+?stylesheet.+?-->/s
感谢所有参与者的有趣答案。
字符串stylesheet
在测试文档中只提到一次,因此您尝试的两个正则表达式将以不同的方式匹配相同的内容。
<!--(?=.*?stylesheet).*?-->/s
这个做了以下几点:
<!--
。 stylesheet
。 如果找不到则失败。 -->
。 <!--(?=.*stylesheet).*?-->/s
这个做了以下几点:
<!--
。 stylesheet
。 如果找不到则失败。 -->
。 基本上,一个人需要显着地回溯,而另一个人则不需要。
如果您的主题是......
<!-- The quick brown fox jumps over the lazy dog --> <!--[if IE 7]> <link rel="" type="text/css" href="/supersheet.css" /> <![endif]--> <!-- Pack my box with five dozen s -->
你得到两个不同的结果。 前者会找到第一个stylesheet
,而后者会找到第二个(和最后一个),因为它从字符串的末尾开始搜索。
要仅匹配<!--
... stylesheet
... -->
,有很多方法:
1.)使用否定连字符[^-]
来限制匹配并保持在<!--
和stylesheet
(?s)<!--[^-]+stylesheet.+?-->
[^-]
仅允许不是连字符的字符。 请参阅regex101上的测试 。
2.)要获得“最后”或最接近的匹配而没有太多正则表达式的努力,也可以在ᗧ吃之前放一个贪婪的 点 。 如果不匹配全局/只匹配一个项目,则有意义。 使用\\ K在贪婪后重置 :
(?s)^.*\K<!--.+?stylesheet.+?-->
请参阅regex101上的测试 。 也可以使用捕获组并获取$ 1:( (?s)^.*(<!--.+?stylesheet.+?-->)
3.)使用前瞻来缩小范围通常更昂贵:
(?s)<!--(?:(?!<!).)+?stylesheet.+?-->
请参阅regex101上的测试 。 (?!<!).
展望<!--
和stylesheet
中的每个角色,如果没有开始另一个<!
......留在一个元素里面 类似于否定的连字符解决方案。
而不是.*
我使用.+
一个或多个 - 取决于匹配什么。 这里+
更合适。
使用什么解决方案取决于具体要求。 对于这种情况,我会使用第一个。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.