php 正则 修饰符,正则表达式中的那些模式修饰符(一)

首先列出当前可用的PCRE修正符、对应的名称以及作用的简单介绍,然后再对这些模式修正符进行举例说明。

i(PCRE_CASELESS)

忽略大小写

// 要匹配开头的 This

$str = "This is a example";

$pattern = '/^this/';

$pattern_i = '/^this/';

$res = preg_match($pattern,$str,$matches);

$res_i = preg_match($pattern_i,$str,$matches_i);

echo "res=>",$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修正符是没任何意义的;或者是正则表达式中没有出现^或者$,该修正符也不产生任何影响。

$str = "

This is not an example

\n That is not mine";

// 不指定 m 修正符

$pattern = '/^

([^$/';

// 指定 m 修正符

$pattern_m = '/^

([^$/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)

有很多地方介绍该修饰符是将多行转换成一行。其实这种说法不太准确。确切来说,应该是如果设置了这个修饰符,模式中的点号元字符匹配所有字符,包含换行符。如果没有这个 修饰符,点号.不匹配换行符。但是对于取反字符来说,比如[^

$str = "

This is not \n an example

";

// 不指定 `s`

$pattern = '/^

(.*)$/';

// 指定 `s`

$pattern_s = '/^

(.*)$/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修饰符的限制,即使不设置也能匹配出换行符。

$str = "

This is not \n an example

";

$pattern = '/^

([^$/';

$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)

如果设置了这个修饰符,正则表达式中出现的空白的数据会被忽略。

$str = "Hello Example!";

$str_nospace = "HelloExample";

$pattern = "/Hello Example/";

$pattern_x = "/Hello Example/x"; // 空格会被忽略

$pattern_x_newline = "/Hello \n Example/x" // 换行符也会被忽略

$res = preg_match($pattern,$str,$matches);

print_r($matches);

/*

Array

(

[0] => 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

)

*/

除了上面介绍的空白数据(空格,换行符等)会被忽略之外,对于正则表达式中的未转义的#和下一个换行符之间的字符也会被忽略。 这样就可以对复杂的正则表达式添加注释了。

$str = "

This is an example

";

$pattern = "/^

# 匹配开始位置

(.*) # 匹配标签内容并捕获

$ # 匹配结尾的

/x";

// 使用换行符也可 $pattern = "/^

# 匹配开始位置

\n (.*) # 匹配标签内容并捕获 \n $ # 匹配结尾的 \n/x"; 为了格式清楚,便于阅读,不推荐使用换行符的形式`\n`而把所有的都写在一行。

$res = preg_match($pattern,$str,$matches);

print_r($matches);

是能匹配到内容

Array

(

[0] =>

This is an example

[1] => This is an example

)

注意:这仅用于数据字符。 空白字符 还是不能在模式的特殊字符序列中出现,比如序列 (?( 引入了一个条件子组(译注: 这种语法定义的 特殊字符序列中如果出现空白字符会导致编译错误。 比如(? 就会导致错误)。

$str = "

This is an example

";

$pattern = "/^

(?.*)$/";

$pattern_space = "/^

(? .*)$/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 ......

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值