正则表达式挑战 - 在HTML文档中找到“foobar”

时间:2009-10-02 14:24:03

标签: regex regex-negation dom

我有一个相当长而复杂的HTML文档,我需要找到给定字符串的所有出现,例如“foobar”,除非它位于<a></a>锚标记之间。

问题是:它可能位于锚标记之间的某些文本中,例如

<a>this is a foobar test</a>

即使在这种情况下,我也应该找到匹配。

我怎么能用正则表达式做到这一点?我会毫不费力地找到<a>foobar</a>等等 - 但是找到每个“foobar”除了,当它位于锚标签之间并被可能的许多其他文本包围时似乎有点棘手...... ...

任何想法??

解答:
我们最终使用这个正则表达式来解决这个问题 - 以防万一有人好奇,或者b)在同一个地方: - )

(?<!\<A.*(?=\<\/A))Test(?!\<\/A.*(?=\<A))

3 个答案:

答案 0 :(得分:2)

'foobar(?![^<]*</a>)'

在最简单的情况下适合我。它显然不能在a标记中包含其他标记。

答案 1 :(得分:1)

你应该能够做出负向前瞻和背后的模式。这是一个很好的教程:

http://www.regular-expressions.info/lookaround.html

答案 2 :(得分:0)

试试这个:

$str = 'foobar <a>this is a foobar <span>foobar</span> test</a> foobar';

$pattern = '<a(?:[^"\'>]+|"[^"]*"|\'[^\']*\')*>(?:[^<]+|(?!<\/a\s*>)<)*<\/a\s*>';
$parts = preg_split('/('.$pattern.')/', $str, -1, PREG_SPLIT_DELIM_CAPTURE);
$isLink = (bool) preg_match('/^'.$pattern.'$/', $parts[0]);
foreach ($parts as &$part) {
    if (!$isLink) {
        $part = str_replace('foobar', '!!!found!!!', $part);
    }
    $isLink = !$isLink;
}
$str = implode('', $parts);

echo htmlspecialchars($str);