更好的问题标题可能是:
"匹配包含特定子字符串的DIV
元素。" 首先必须说明的是,正则表达式不是这项工作的最佳工具。最好使用HTML解析器解析标记,然后在每个
DIV
元素的内容中搜索所需的子字符串。尽管如此,既然您想了解如何使用正则表达式匹配不是其他东西的内容,下面将介绍一种有限的使用正则表达式的方法。
正如Dogbert所指出的那样,这个问题实际上是
另一个问题的重复。但是,我看到您已经查看了那个问题,但需要知道如何将此技术应用于子模式。
要匹配不包含特定单词(或单词)的字符串部分(子模式),您需要在每个字符之前应用负向先行断言检查。以下是如何在打开和关闭
DIV
标记之间执行此操作的方法。请注意,当仅使用单个正则表达式时,由于
DIV
元素可以嵌套,因此只能在嵌套的
DIV
元素的“内部”找到
"HELLO"
。
伪代码:
- 匹配打开的
DIV
标记。
- 懒惰地匹配零个或多个字符,每个字符都不是
<div
或
</div
的开头。
- 一旦找到所需的字符串:
"HELLO"
,请继续匹配它。
- 继续(贪婪地)匹配零个或多个字符,每个字符都不是
<div
或
</div
的开头。
- 匹配关闭的
</div>
标记。
请注意,在逐个字符扫描元素内容时,为了仅匹配“最内层”的
DIV
内容,有必要同时排除
<DIV
和
</DIV
。下面是相应的正则表达式,以测试PHP函数的形式呈现:
function p1($text) {
$re = '% # Match innermost DIV element containing "HELLO"
<div[^>]*> # DIV element start tag.
(?: # Group to match contents up to "HELLO".
(?!</?div\b) # Assert this char is not start of DIV tag.
. # Safe to match this non-DIV-tag char.
)*? # Lazily match contents one chara at a time.
\bhello\b # Match target "HELLO" word inside DIV.
(?: # Group to match content following "HELLO".
(?!</?div\b) # Assert this char is not start of DIV tag.
. # Safe to match this non-DIV-tag char.
)* # Greedily match contents one chara at a time.
</div> # DIV element end tag.
%six';
if (preg_match($re, $text, $matches)) {
return $matches[0];
} else {
return 'no-match';
}
}
这个函数将正确匹配您的以下测试数据中所需的DIV元素:
<div>Bye.</div><div>Hello!</div>
它还可以正确地在嵌套的 DIV 元素中最内层找到 "HELLO":
<div>
<div>
Hello world!
</div>
</div>
但是,正如之前所述,它将不会在非最内层嵌套的DIV元素中找到位于其中的"HELLO"字符串,如下所示:
<div>
Hello,
<div>
world!
</div>
</div>
要实现这个功能需要一个更为复杂的解决方案。
这种方法很容易出现许多问题。因此,我建议使用HTML解析器。