正则学习 入门+preg_match_all
http://deerchao.net/tutorials/regex/regex.htm 正则基础
http://blog.163.com/i_yuhan/blog/static/198342100201242382436322/ preg_match_all 及实例
PREG_MATH_ALL:进行全局正则表达式匹配
int preg_match_all ( string $pattern , string $subject , array $matches [, int $flags ] )
flags 可以是下列标记的组合(注意把 PREG_PATTERN_ORDER 和 PREG_SET_ORDER 合起来用没有意义):
- PREG_PATTERN_ORDER
- 对结果排序使 $matches[0] 为全部模式匹配的数组,$matches[1] 为第一个括号中的子模式所匹配的字符串组成的数组,以此类推。
-
1 <?php 2 preg_match_all ("|<[^>]+>(.*)</[^>]+>|U", 3 "<b>example: </b><div align=left>this is a test</div>", 4 $out, PREG_PATTERN_ORDER); 5 print $out[0][0].", ".$out[0][1]."\n"; 6 print $out[1][0].", ".$out[1][1]."\n"; 7 ?>
本例将输出:
<b>example: </b>, <div align=left>this is a test</div> example: , this is a test
-
因此,$out[0] 包含匹配整个模式的字符串,$out[1] 包含一对 HTML 标记之间的字符串。
- PREG_SET_ORDER
- 对结果排序使 $matches[0] 为第一组匹配项的数组,$matches[1] 为第二组匹配项的数组,以此类推。
<?php preg_match_all ("|<[^>]+>(.*)</[^>]+>|U", "<b>example: </b><div align=left>this is a test</div>", $out, PREG_SET_ORDER); print $out[0][0].", ".$out[0][1]."\n"; print $out[1][0].", ".$out[1][1]."\n"; ?>
本例将输出:
<b>example: </b>, example: <div align=left>this is a test</div>, this is a test
-
本例中,$matches[0] 是第一组匹配结果,$matches[0][0] 包含匹配整个模式的文本,$matches[0][1] 包含匹配第一个
-
子模式的文本,以此类推。同样,$matches[1] 是第二组匹配结果,等等。
- PREG_OFFSET_CAPTURE
-
如果设定本标记,对每个出现的匹配结果也同时返回其附属的字符串偏移量。注意这改变了返回的数组的值,使其中的每个单元也是一个数组,其中第一项为匹配字符串,第二项为其在 subject 中的偏移量。本标记自 PHP 4.3.0 起可用。
如果没有给出标记,则假定为 PREG_PATTERN_ORDER。
===========================================================================================
详解如下:
$html = '<div id="biuuu">51CTO</div><div id="biuuu_2">51CTO2</div><div id="biuuu_3">51CTO3</div>';
要求:分别将每一个DIV元素的ID和内容取出,如biuuu,biuuu_2,biuuu_3,51CTO,51CTO2和51CTO3(一些常用的抓站方法就是这样匹配的)
分析:字符串是一个简单的HTML元素,每一个DIV元素对应该一个ID和内容,并且是独立的,首先考虑如何取出一个DIV内的ID值和内容,如:51CTO,然后匹配其它类似的元素。一个DIV中需要取出两个值,也就是两个匹配的表达式,第一个表达式用于匹配ID值(biuuu),第二个表达式用于匹配ID的内容(51CTO),正则表达式常用的表达式使用小括号,那么前面的元素将会变成如下形式:
<div id="(biuuu)">(51CTO)</div>
对应匹配格式为
<div id="(表达式1)">(表达式2)</div>
使用如上小括号把需要匹配的区域进行了划分,接下来就是如何匹配各个表达式内的内容,我们猜想一个ID可能是字母,数字或下划线,那这就变得简单了,使用中括号就可以实现,如下:
表达式1:[a-zA-Z0-9_]+ (表示匹配大小写字母,数字和下划线)
如何匹配表达式2,因为ID的内容可以是任意的字符,但是要注意,不能匹配<或>字符,因为如果匹配这两个字符将会把后面使用的DIV都匹配出来,因此需要排除这两个字符开始的元素,也就是不匹配以<或>字符,如下:
表达式2:[^<>]+ (表示不匹配<和>字符)
(^放在[](中括号)里表示非,即不接受该字符集合,不在[]里则代表匹配输入字符串的开始位置)
这样,需要匹配的子表达式就实现了,但是还要需要匹配一个完整的的表达式,方法如下:
表达式:/ '\"(表达式1)\"'>(表达式2)<\/div>/
注意其中的双引号"和/需要使用\转义字符转义,然后把前面两个表达式放进去,如下:
'\"([a-z0-9_]+)\"'>
/<div id=\"([a-z0-9_]+)\">([^<>]+)<\/div>/
最终完整的结果为:
preg_match_all('/<div\sid=\"([a-z0-9_]+)\">([^<>]+)<\/div>/',$html,$result);
var_dump($result);
结果
array(3) { [0]=> array(3) { [0]=> string(30) "<div id="biuuu">51CTO</div>"
[1]=> string(33) "<div id="biuuu_2">51CTO2</div>"
[2]=> string(33) "<div id="biuuu_3">51CTO3</div>" }
[1]=> array(3)
{ [0]=> string(5) "biuuu" [1]=> string(7) "biuuu_2"
[2]=> string(7) "biuuu_3" }
[2]=> array(3) {
[0]=> string(8) "51CTO" [1]=> string(9) "51CTO2" [2]=> string(9) "51CTO3" } }
结果为数组,有三个元素,
第一个元素为全模式匹配的数组结果, 即:
[0]=> array(3)
{ [0]=> string(30) "<div id="biuuu">51CTO</div>" [1]=> string(33) "<div id="biuuu_2">51CTO2</div>" [2]=> string(33) "<div id="biuuu_3">51CTO3</div>" }
第二个元素为第一个子表达式(括号)匹配后的结果所组成的数组,即
[1]=> array(3) { [0]=> string(5) "biuuu" [1]=> string(7) "biuuu_2" [2]=> string(7) "biuuu_3" }
第三个元素为第二个子表达式(括号)匹配后的结果所组成的数组,即
[2]=> array(3) { [0]=> string(8) "51CTO" [1]=> string(9) "51CTO2" [2]=> string(9) "51CTO3" } }
===================================================
其他范例:要求获取<a></a>里的值
<?php
$s = <<< TXT
.....
<span class="singer" style="width: 95px;">
<a href="artist/001">json</a>
</span>
.....
<span class="singer" style="width: 95px;">
<a href="artist/002">ajax</a>
</span>
....
<span class="singer" style="width: 95px;">
<a href="artist/003">php</a>
<span>/</span>
<a href="artist/004">mysql</a>
</span>
TXT;
preg_match_all("/<span.+<a.+>(.+)</isU", $s, $r);
print_r($r[1]);
结果为Array ( [0] => json [1] => ajax [2] => php [3] => mysql )

浙公网安备 33010602011771号