正则表达式教程 正则表达式 正则 教程 PHP 技术 正则表达式教程四 —— 模式修饰符(PHP) 2017-12-20 17:22 2824 更新于 2017-12-20 17:41 今天讲一讲php中的正则修饰符 大概有这么几个,i , m , s , x , e , A , E , U 下面就来一一介绍下 ## 1、i 忽略大小写,若加上i,则正则将会取消大小写敏感性,比如 a 和 A 都可匹配 ### 例子 15 ```php $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 ```php $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 ```php $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 ```php $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 ```php $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` 吧,如下 ```php 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 ```php $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 ```php $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` ,而使用 `?` ,如何实现呢? 很简单:`#([\s\S]*?)#` ## 9、u 使用 unicode 来匹配字符集,模式字符串被认为是utf-8的 ### 例子22 ```php 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` (日文)