今天讲一讲php中的正则修饰符
大概有这么几个,i , m , s , x , e , A , E , U
下面就来一一介绍下
1、i
忽略大小写,若加上i,则正则将会取消大小写敏感性,比如 a 和 A 都可匹配
例子 15
$s = <<<'TEXT' aBcDeFg TEXT; preg_match_all('#[a-z]#',$s,$m); echo "<pre>"; print_r($m); echo "</pre>"; /* Array ( [0] => Array ( [0] => a [1] => c [2] => e [3] => g ) ) */
这样只能匹配到小写的字母,若加上 i 修饰符
preg_match_all('#[a-z]#i',$s,$m); /* Array ( [0] => Array ( [0] => a [1] => B [2] => c [3] => D [4] => e [5] => F [6] => g ) ) */
2、m
默认的正则开始"^"和结束"$"只是对于正则字符串,如果加上修饰符"m",那么开始和结束将会指字符串的每一行:每一行的开头就是"^",结尾就是"$"。
例子 16
$s = <<<'TEXT' 02312345678 01088665752 02345765418 TEXT; preg_match_all('#^023\d+#m',$s,$m); echo "<pre>"; print_r($m); echo "</pre>"; /* Array ( [0] => Array ( [0] => 02312345678 [1] => 02345765418 ) ) */
匹配以023开头的电话,若去掉修饰符 ,则结果为
Array ( [0] => Array ( [0] => 02312345678 ) )
3、 s
如果在修饰符中加入"s",那么默认的"."代表除了换行符以外的任何字符将会变成任意字符,也就是包括换行符!
也就是说 . 能匹配任意字符
例子17
$s = <<<'TEXT' <div> content </div> TEXT; preg_match_all('#<div>.+?</div>#',$s,$m); echo "<pre>"; print_r($m); echo "</pre>"; /* Array ( [0] => Array ( [0] => <div> content </div> ) ) */
若去掉修饰符 s ,则不能匹配内容
4、x
如果加上该修饰符,表达式中的空白字符将会被忽略,除非它已经被转义。
例子18
$s = <<<'TEXT' <img src="https://www.baidu.com/"> TEXT; preg_match_all('#<img src="([\s\S]*?)">#',$s,$m); echo "<pre>"; print_r($m); echo "</pre>"; /* Array ( [0] => Array ( [0] => <img src="https://www.baidu.com/"> ) [1] => Array ( [0] => https://www.baidu.com/ ) ) */
匹配img中的图片链接,表达式中我使用了空格,若加上修饰符 x ,则空格被忽略,不能匹配到任何内容
5、e
本修饰符仅仅对于replacement有用,代表在replacement中作为PHP代码
这个修饰符也经常使用,不过在新版本的php 中不推荐在 preg_replace 中使用修饰符 e 来调用方法替换
请使用 preg_replace_callback 来代替
例子19
$s = <<<'TEXT' 测试文本1 <a href="http://www.baidu.com">链接</a> 测试文本2 TEXT; echo preg_replace('#<a href="([^"]+?)">([^<]+?)</a>#e',"myFunc('$1','$2')",$s); function myFunc($m1,$m2){ return "[link=$m1]$m2-替换后[/link]"; } //测试文本1 [link=http://www.baidu.com]链接-替换后[/link] 测试文本2
$1 和 $2 就是使用 () 捕获的内容,在 myFunc() 方法中组织好替换的内容然后返回
不过就像刚刚说的,在 preg_replace 中已经不推荐使用修饰符 e,还是乖乖的用 preg_replace_callback 吧,如下
echo preg_replace_callback('#<a href="([^"]+?)">([^<]+?)</a>#',function($m){ return myFunc($m[1],$m[2]); },$s); function myFunc($m1,$m2){ return "[link=$m1]$m2-替换后[/link]"; }
结果是一样的;首先去掉修饰符 e,然后在 callback 中调用 myFunc,$m 为匹配到的内容
注:可以使用这种方法替换掉以前的老代码,是不是很方便
6、A
如果使用这个修饰符,那么表达式必须是匹配的字符串中的开头部分。比如说"/b/A"匹配"bcd"。
这个还是很少使用的
例子20
$s = <<<'TEXT' bcd TEXT; preg_match('#b#A',$s,$m); echo "<pre>"; print_r($m); echo "</pre>"; /* Array ( [0] => b ) */
这样是可以匹配 b 的,但将匹配的字符串改为 cbd ,就不能匹配了
7、E
与"m"相反,如果使用这个修饰符,那么"$"将匹配绝对字符串的结尾,而不是换行符前面,默认就打开了这个模式。
既然是默认打开,我们就不讲了,哈哈
8、U
和问号的作用差不多,用于设置"贪婪模式"
例子21
$s = <<<'TEXT' <div>abc一</div><div>def二</div> TEXT; preg_match_all('#<div>([\s\S]*)</div>#',$s,$m); echo "<pre>"; print_r($m); echo "</pre>"; /* Array ( [0] => Array ( [0] => <div>abc一</div><div>def二</div> ) [1] => Array ( [0] => abc一</div><div>def二 ) ) */ preg_match_all('#<div>([\s\S]*)</div>#U',$s,$m); echo "<pre>"; print_r($m); echo "</pre>"; /* Array ( [0] => Array ( [0] => <div>abc一</div> [1] => <div>def二</div> ) [1] => Array ( [0] => abc一 [1] => def二 ) ) */
匹配标签 div 中的所有内容,还记得上一节中讲的如何匹配所有字符吗,对,就是 [\s\S]
上一个正则没有加修饰符 U ,则将后面所有内容都匹配到了(因为有多个 div 标签)
加了修饰符 U 的正则,则匹配到了两个div中的内容,这才是我们想要的
那不用修饰符 U ,而使用 ? ,如何实现呢?
很简单:#<div>([\s\S]*?)</div>#
9、u
使用 unicode 来匹配字符集,模式字符串被认为是utf-8的
例子22
preg_match_all('/[\x{4e00}-\x{9fa5}]+/u','中12国j',$m); echo "<pre>"; print_r($m); echo "</pre>"; /* Array ( [0] => Array ( [0] => 中 [1] => 国 ) ) */
匹配 utf-8 的中文
这里说一下中日韩的编码范围
u4e00-u9fa5 (中文)
x3130-x318F (韩文)
xAC00-xD7A3 (韩文)
u0800-u4e00 (日文)