正则表达式教程四 —— 模式修饰符(PHP)
2017-12-20 17:22 浏览(1986 更新于 2017-12-20 17:41

今天讲一讲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 (日文)


评论(2)
发布评论
回复X
聊天室(0