php中的模式修饰符 一——迹忆客-ag捕鱼王app官网
模式修饰符
首先列出当前可用的pcre修正符、对应的名称以及作用的简单介绍,然后再对这些模式修正符进行举例说明。
i
(pcre_caseless)
忽略大小写
",$res,"\n";
echo "res_i=>",$res_i,"\n";
res=>0
res_i=>1
m
(pcre_multiline)
将目标字符串按照换行符'\n
'进行分行匹配(默认情况下,pcre认为目标字符串是单行的,实际上很多情况下是包含多行的)。比如说 this is an example \n that is great!
,这个字符串其实是两行,如果不指定m
修正符,则pcre在进行匹配的时候默认是按照一行匹配的。也就是说 "行首"元字符 ^
是从整个字符串的开始位置进行匹配,而 "行末" 元字符 $
是匹配整个字符串的末尾。 如果指定了m
修正符,则字符串是按照换行符\n
进行分行,^
和$
是匹配每一行的开始和结尾位置。 所以说,如果目标字符串中没有包含换行符\n
,那么设置m
修正符是没任何意义的;或者是正则表达式中没有出现 ^
或者$
,该修正符也不产生任何影响。
this is not an example\n"; // 不指定 m 修正符 $pattern = '/^
([^<] )<\/p>$/'; // 指定 m 修正符 $pattern_m = '/^
([^<] )<\/p>$/m'; $res = preg_match($pattern,$str,$matches); $res_m = preg_match($pattern_m,$str,$matches_m); print_r($matches); print_r($matches_m);
上面的执行结果
// 未指定 m
array
(
)
// 指定 m
array
(
[0] => this is not an example
[1] => this is not an example
)
上面的正则是在行首
和行末
匹配
和
。所以不能匹配。 指定m
之后,目标字符串被分成多行,^
和$
是匹配每行的开始和结尾位置,所以就可以将内容匹配出来。
s
(pcre_dotall)
有很多地方介绍该修饰符是将多行转换成一行。其实这种说法不太准确。确切来说,应该是如果设置了这个修饰符,模式中的点号元字符匹配所有字符,包含换行符。如果没有这个 修饰符,点号.
不匹配换行符。但是对于取反字符来说,比如[^<],是可以匹配换行符的,不管是否设置了这个修饰符。
this is not \n an example"; // 不指定 `s` $pattern = '/^
(.*)<\/p>$/'; // 指定 `s` $pattern_s = '/^
(.*)<\/p>$/s'; $res = preg_match($pattern,$str,$matches); $res_s = preg_match($pattern_s,$str,$matches_s); print_r($matches); print_r($matches_s);
// 不指定 s
array
(
)
// 指定 s
array
(
[0] => this is not
an example
[1] => this is not
an example
)
可以看出,如果不指定s
点号.
是不能匹配到换行符\n
所以对于第一个结果是匹配不到。对于取反字符就不受s
修饰符的限制,即使不设置也能匹配出换行符。
this is not \n an example"; $pattern = '/^
([^<] )<\/p>$/'; $res = preg_match($pattern,$str,$matches); print_r($matches);
array
(
[0] => this is not
an example
[1] => this is not
an example
)
鉴于
s
和m
修饰符都涉及到了换行符\n
, 这里值得一提的是在 php 中的字符串如果是在单引号(' ') 中,其中的特殊符号的作用都失效,相当于普通的字符。只有在双引号中(" ")的才有效。 也就是说,目标字符串如果是单引号指定的,关于换行符的模式修饰符都不会产生影响。
x
(pcre_extended)
如果设置了这个修饰符,正则表达式中出现的空白的数据会被忽略。
hello example
)
*/
$res = preg_match($pattern_x,$str,$matches);
print_r($matches);
/*
array
(
)
*/
$res = preg_match($pattern_x,$str_nospace,$matches);
print_r($matches);
/*
array
(
[0] => helloexample
)
*/
$res = preg_match($pattern_x_newline,$str_nospace,$matches);
print_r($matches);
/*
array
(
[0] => helloexample
)
*/
除了上面介绍的空白数据(空格,换行符等)会被忽略之外,对于正则表达式中的未转义的#
和下一个换行符之间的字符也会被忽略。 这样就可以对复杂的正则表达式添加注释了。
this is an example"; $pattern = "/^
# 匹配开始位置
(.*) # 匹配标签内容并捕获 <\/p>$ # 匹配结尾的<\/p> /x"; // 使用换行符也可 $pattern = "/^
# 匹配开始位置
\n (.*) # 匹配标签内容并捕获 \n <\/p>$ # 匹配结尾的<\/p> \n/x"; 为了格式清楚,便于阅读,不推荐使用换行符的形式`\n`而把所有的都写在一行。 $res = preg_match($pattern,$str,$matches); print_r($matches);
是能匹配到内容
array
(
[0] => this is an example
[1] => this is an example
)
注意:这仅用于数据字符。 空白字符 还是不能在模式的特殊字符序列中出现,比如序列(?(
引入了一个条件子组(译注: 这种语法定义的 特殊字符序列中如果出现空白字符会导致编译错误。 比如(?
就会导致错误)。
this is an example"; $pattern = "/^
(?
.*)<\/p>$/"; $pattern_space = "/^
(?
.*)<\/p>$/x"; $res = preg_match($pattern,$str,$matches); $res = preg_match($pattern_space,$str,$matches_space); print_r($matches); print_r($matches_space);
上面例子我们在给子组命名,第一个?
和
之间没有空格;第二个?
和
存在一个空格,并且设置了x
。执行结果如下
// 没空格
array
(
[0] => this is an example
[name] => this is an example
[1] => this is an example
)
// 有空格的就会产生 warning 错误
php warning: preg_match(): compilation failed: unrecognized character after (? or (?- at offset 6 in ......