迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 >

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

作者:迹忆 最近更新:2022/12/12 浏览次数:

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

i (PCRE_CASELESS)

忽略大小写

<?php
// 要匹配开头的 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修正符是没任何意义的;或者是正则表达式中没有出现 ^或者$,该修正符也不产生任何影响。

<?php
$str = "<p>This is not an example</p>\n<a>That is not mine</a>";
// 不指定 m 修正符
$pattern = '/^<p>([^<]+)<\/p>$/';
// 指定 m 修正符
$pattern_m = '/^<p>([^<]+)<\/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] => <p>This is not an example</p>
    [1] => This is not an example
)

上面的正则是在行首行末匹配<p></p> ,目标字符串按照一行来匹配的话,行末是</a>。所以不能匹配。 指定m之后,目标字符串被分成多行,^$是匹配每行的开始和结尾位置,所以就可以将内容匹配出来。

s (PCRE_DOTALL)

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

<?php
$str = "<p>This is not \n an example</p>";
// 不指定 `s`
$pattern = '/^<p>(.*)<\/p>$/';
// 指定 `s`
$pattern_s = '/^<p>(.*)<\/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] => <p>This is not an example</p>
    [1] => This is not an example
)

可以看出,如果不指定s 点号. 是不能匹配到换行符\n 所以对于第一个结果是匹配不到。对于取反字符就不受s修饰符的限制,即使不设置也能匹配出换行符。

<?php
$str = "<p>This is not \n an example</p>";
$pattern = '/^<p>([^<]+)<\/p>$/';
$res = preg_match($pattern,$str,$matches);
print_r($matches);

上面的执行结果

Array
(
    [0] => <p>This is not an example</p>
    [1] => This is not an example
)

注:鉴于 s  m 修饰符都涉及到了换行符\n , 这里值得一提的是在 PHP 中的字符串如果是在单引号(' ') 中,其中的特殊符号的作用都失效,相当于普通的字符。只有在双引号中(" ")的才有效。 也就是说,目标字符串如果是单引号指定的,关于换行符的模式修饰符都不会产生影响。

x (PCRE_EXTENDED)

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

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

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

<?php
$str = "<p>This is an example</p>";
$pattern = "/^<p> # 匹配开始位置<p>
            (.*)  # 匹配标签内容并捕获
            <\/p>$ # 匹配结尾的<\/p>
            /x";
// 使用换行符也可 $pattern = "/^<p> # 匹配开始位置<p> \n (.*)  # 匹配标签内容并捕获 \n <\/p>$ # 匹配结尾的<\/p> \n/x";  为了格式清楚,便于阅读,不推荐使用换行符的形式`\n`而把所有的都写在一行。
$res = preg_match($pattern,$str,$matches);
print_r($matches);

是能匹配到内容

Array
(
    [0] => <p>This is an example</p>
    [1] => This is an example
)

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

<?php
$str = "<p>This is an example</p>";
$pattern = "/^<p>(?<name>.*)<\/p>$/";
$pattern_space = "/^<p>(? <name>.*)<\/p>$/x";
$res = preg_match($pattern,$str,$matches);
$res = preg_match($pattern_space,$str,$matches_space);


print_r($matches);

print_r($matches_space);

上面例子我们在给子组命名,第一个?<name> 之间没有空格;第二个?<name>存在一个空格,并且设置了x。执行结果如下

// 没空格
Array
(
    [0] => <p>This is an example</p>
    [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 ......

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

C# 中的默认访问修饰符

发布时间:2024/02/01 浏览次数:118 分类:编程语言

在本指南中,我们将了解 C# 中的访问修饰符。什么是访问修饰符及其默认状态?你如何使用它们,你使用它们的目的是什么?

Python 中不区分大小写的正则表达式

发布时间:2023/12/20 浏览次数:114 分类:Python

本文包括两种在文本中搜索模式的方法。一种方法是使用 re.IGNORECASE 标志和 re.I 标志,第二种方法是使用(?i) 表示的不区分大小写的标记。

Java 中的默认访问修饰符

发布时间:2023/10/18 浏览次数:156 分类:Java

本文介绍 Java 中的默认访问修饰符在本教程中,我们将讨论 Java 中的默认访问修饰符。顾名思义,当我们不使用变量或函数指定任何人时,使用访问修饰符。

Python - 匹配多行文本块的正则表达式

发布时间:2023/06/02 浏览次数:311 分类:Python

本文讨论了在多行字符串中搜索特定模式的方法。 该解决方案折衷了已知和未知模式的几种方法,并解释了匹配模式的工作原理。编写正则表达式以匹配多行字符串的原因

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便