Dan*_*ark 12 regex non-greedy reluctant-quantifiers regex-greedy
我总是写这样的正则表达式
<A HREF="([^"]*)" TARGET="_blank">([^<]*)</A>
Run Code Online (Sandbox Code Playgroud)
但我刚刚了解了这个懒惰的东西,我可以这样写
<A HREF="(.*?)" TARGET="_blank">(.*?)</A>
Run Code Online (Sandbox Code Playgroud)
使用第二种方法有什么不利之处吗?正则表达式肯定更紧凑(即使SO更好地解析它).
编辑:这里有两个最佳答案,指出表达式之间的两个重要差异.ysth的答案指向非贪婪/懒惰的弱点,其中超链接本身可能包含A标签的其他属性(绝对不好).Rob Kennedy在贪婪的例子中指出了一个弱点,因为锚文本不能包含其他标签(绝对不行,因为它也不会抓住所有的锚文本)......所以答案是,正则表达式就是他们的是,懒惰和非懒惰的解决方案似乎相同可能在语义上不等同.
编辑:第三个最佳答案是Alan M关于表达式的相对速度.暂时,我会将他标记为最佳答案,以便人们给他更多积分:)
Ala*_*ore 12
另一件需要考虑的事情是目标文本的持续时间,以及量化的子表达式将匹配多少.例如,如果您尝试匹配大型HTML文档中的整个<BODY>元素,则可能会尝试使用此正则表达式:
/<BODY>.*?<\/BODY>/is
Run Code Online (Sandbox Code Playgroud)
但这会做很多不必要的工作,一次匹配一个角色,同时在每个角色之前有效地做出负面的预测.你知道</ BODY>标签将非常接近文档的末尾,所以聪明的做法是使用正常的贪心量词; 让它淹没文档的其余部分,然后回溯匹配结束标记所需的几个字符.
在大多数情况下,你不会注意到贪婪和不情愿量词之间的任何速度差异,但要记住这一点.你在使用不情愿的量词时应该明智的主要原因是其他人指出的一个:他们可能不情愿地做到这一点,但是如果这是实现整体所需要的,那么它们将比你想要的更多.比赛.
补充的字符类更严格地定义了您想要匹配的内容,所以无论何时,我都会使用它.
非贪婪的正则表达式将匹配您可能不想要的东西,例如:
<A HREF="foo" NAME="foo" TARGET="_blank">foo</A>
Run Code Online (Sandbox Code Playgroud)
你的第一个.*?火柴
foo" NAME="foo
Run Code Online (Sandbox Code Playgroud)
请注意,您的示例不相同.您的第一个正则表达式不会选择包含其他标记的任何链接,例如img或b.第二个正则表达式,我希望这可能是你想要的.
除了意义上的差异之外,我能想到的唯一缺点是对非贪婪修饰语的支持并不像字符类否定那样普遍.在我检查之前,它比我想象的更广泛支持,但值得注意的是列表中没有GNU Grep.如果您正在使用的正则表达式求值程序支持它,那么继续使用它.