我创建了一个匹配在a
标签之间的三个数字字符串(例如:333)的模式:
@((<a>(.?[^(<\/a>)].?))*)([0-9]{3})(((.*?)?</a>))@i
如何将上述模式反转,以获取不在a
标签之间的数字。
我尝试使用?!
但没有成功。
编辑: 示例输入数据:
lor <a>111</a> em 222 ip <a><link />333</a> sum 444 do <a>x555</a> lo <a>z 666</a> res
你正在尝试在文本领域解决HTML问题,这很难使用。正确的方法是使用DOM解析器;您可以使用XPath表达式来过滤您想要的内容:
$doc = new DOMDocument();
$doc->loadHTML($html);
$xpath = new DOMXPath($doc);
foreach ($xpath->query('//text()[not(ancestor::a)]') as $node) {
if (preg_match('/\d{3}/', $node->textContent)) {
// do stuff with $node->textContent;
}
}
kicaj,这种情况听起来与正则表达式匹配模式除外...非常相似。
尽管使用正则表达式解析HTML需要注意一些免责声明,但有一种简单的方法可以实现。
以下是我们的简单正则表达式(请参见演示):
<a.*?</a>(*SKIP)(*F)|\d{3}
替换符号|
的左侧匹配完整的<a ... </a>
标记,然后故意失败并跳到字符串中的下一个位置。右侧匹配三位数字的组,我们知道它们是正确的数字,因为左侧表达式没有匹配到它们。
请注意,如果您只想精确匹配三个数字,而不是更多数字中的三个数字,例如在12345
中的123
,您可能需要添加负向前瞻和负向后顾:
<a.*?<\/a>(*SKIP)(*F)|(?<!\d)\d{3}(?!\d)
参考资料
[^(<\/a>)]
并不能做你想要的那样。 - Ja͢ck([^((<a>(.?[^(<\/a>)].?))*)])
但不起作用。 - kicaja
标签之间只有数字还是其他内容也有?只有一组数字还是多组? - Robin