需求

<div class="build_list">谢谢谢谢谢谢谢</div>
...
<div class="build_list">哈哈哈哈哈</div>
...
<div class="abc">嘿嘿嘿</div>

如上一段html标签,要求

  • 匹配到div标签中的内容
  • 不包括div标签本身
  • div的属性可变

预备知识

  1. 正则表达式匹配基本知识,相关知识传送门
  2. html标签语法知识

正则表达式实现

(?<=\<div.*?\>)(.*?)(?=\<\/div\>)

语句解释:

  • (.*?) 使用了懒惰模式,否则会匹配过多的内容
  • 内容两边使用零宽断言,只匹配div标签包裹的内容

PHP编码实现

note :php中正则表达式支持并不完整,不支持后发断言中表达式含有量词(先发断言支持),所以不能实现div标签属性改变时动态匹配。
具体实现如下

1
2
3
preg_match_all('$(?<=\<div\sclass=\"build_list\"\>)(.*?)(?=\<\/div\>)$',$string,$content);
preg_match_all('$(?<=\<div.*?\>)(.*?)(?=\<\/div\>)$',$string,$errorContent);
var_dump($content);

输出如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Warning: preg_match_all(): Compilation failed: lookbehind assertion is not fixed length at offset 14 in /Users/wudanyang/self/php_study/test/test.php on line [$line_number]
array(2) {
[0]=>
array(2) {
[0]=>
string(21) "谢谢谢谢谢谢谢"
[1]=>
string(15) "哈哈哈哈哈"
}
[1]=>
array(2) {
[0]=>
string(21) "谢谢谢谢谢谢谢"
[1]=>
string(15) "哈哈哈哈哈"
}
}


总结

实现这个功能需要对正则表达式中的零宽断言有一定的了解,并且能够看懂html语法。html很容易看懂,但是零宽断言就有点绕弯子。但是只要记住带小于号的都在要匹配的内容的前面,不带小于号的在后面。这样正则表达式就容易写出来了。

正则表达式相关知识传送门
html相关知识传送门