我希望匹配>
后的所有文字,并可选择匹配同一行上的链接:
preg_match('#(href="([^"]*))?.*>(.*)#', '<a href="world.html">Hello', $m);
print_r($m);
输入示例:
<a href="#catch-me" style="nice">Capture this text
This text should be ignored <a href="#me-too">Other text to capture
<p>This line has no link, but should be matched anyway.
预期结果:
[2] => world.html
[3] => Hello
实际结果:
[2] =>
[3] => Hello
如果我删除了问号,它会起作用,但是链接显然不再是可选的。
为什么会发生这种情况,我该如何解决?
答案 0 :(得分:2)
在处理.*
后面的可选子模式时,必须非常小心。
关键是,在可选模式之后的.*
几乎总是&#34;采取&#34;可选的子模式值。你的正则表达式适用于像href="world.html">Hello
这样的字符串。但如果它之前有其他符号则不行。
查看:当您try your regex对<a href="world.html">Hello
时,可以匹配空字符串的(href="([^"]*))?
(遇到非匹配符号时不会失败) ,匹配开头<
之前的位置。然后,.*
发挥作用并匹配所有直到结束,并开始回溯。因此,表达式找到最后一个>
,然后(.*)
将该行的其余部分捕获到第3组。
因此,您可以将您的值与(href="([^"]*))?(?:(?!href=")[^>])*>(.*)
tempered greedy token(与(?:(?!href=")[^>])*
序列不匹配)的beforeunload documentation正则表达式匹配,或者将任务拆分为2个操作(是的,最好是):
1)抓住所有链接
2)检查可选值。