PHP preg反转

4

我创建了一个匹配在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

5
[^(<\/a>)]并不能做你想要的那样。 - Ja͢ck
1
或许正则表达式不是这项工作的合适工具。 - JJJ
@Jack:我尝试过([^((<a>(.?[^(<\/a>)].?))*)])但不起作用。 - kicaj
对于简单的标签,您可以使用负回顾/前瞻像这样 - yate
你能提供一个输入的例子吗?a标签之间只有数字还是其他内容也有?只有一组数字还是多组? - Robin
@Robin,我添加了输入数据。 - kicaj
2个回答

5

你正在尝试在文本领域解决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;
    }
}

0

kicaj,这种情况听起来与正则表达式匹配模式除外...非常相似。

尽管使用正则表达式解析HTML需要注意一些免责声明,但有一种简单的方法可以实现。

以下是我们的简单正则表达式(请参见演示):

<a.*?</a>(*SKIP)(*F)|\d{3}

替换符号|的左侧匹配完整的<a ... </a>标记,然后故意失败并跳到字符串中的下一个位置。右侧匹配三位数字的组,我们知道它们是正确的数字,因为左侧表达式没有匹配到它们。

请注意,如果您只想精确匹配三个数字,而不是更多数字中的三个数字,例如在12345中的123,您可能需要添加负向前瞻和负向后顾:

<a.*?<\/a>(*SKIP)(*F)|(?<!\d)\d{3}(?!\d)

参考资料

如何匹配(或替换)除了s1、s2、s3等情况之外的模式


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接