你能解释一下这是如何工作的吗?这是一个例子:
<!-- 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
它失败了,因为正则表达式匹配 first<!--
和 last之前的所有内容-->
。然后我尝试使用另一种带有前瞻断言的模式:
/<!--(?=.*?stylesheet).*?-->/s
它可以工作并且完全符合我的需要。但是,以下正则表达式也可以工作:
/<!--(?=.*stylesheet).*?-->/s
最后一个正则表达式在前瞻断言中没有不情愿的量词。现在我很困惑。谁能解释一下它是如何工作的?也许这个例子有更好的解决方案?
更新:
我尝试在另一个文档中使用带有前瞻断言的正则表达式,但它无法匹配注释之间的内容。所以,这个/<!--(?=.*?stylesheet).*?-->/s
(以及这个/<!--(?=.*stylesheet).*?-->/s
)是不正确的。不要使用它并尝试其他建议。
更新:
Jonny 5找到了解决方案(见答案)。他提出了三个选择:
- 使用否定的连字符来限制匹配。仅当标签之间没有连字符时,此选项才有效。如果样式表有 URL
/style-sheet.css
,它将不起作用。 - 使用转义序列:
\K
. 它就像一个魅力。缺点如下:- 它非常慢(在我的情况下,它比其他解决方案慢 8-10 倍)
- 仅自 PHP 5.2.4 起可用
- 使用前瞻来缩小匹配范围。这是我试图实现的目标,但我使用环视断言的经验不足以执行任务。
我认为以下是我的示例的一个很好的解决方案:
/(?s)<!--(?:(?!<!).)+?stylesheet.+?-->/
相同,但s
末尾有修饰符:
/<!--(?:(?!<!).)+?stylesheet.+?-->/s
正如我所说,这是一个很好的解决方案,但我设法改进了模式并找到了另一个在我的情况下工作得更快的模式。
所以,最终的解决方案如下:
/<!--(?:(?!-->).)+?stylesheet.+?-->/s
感谢所有参与者提供有趣的答案。