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

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
)

鉴于 sm 修饰符都涉及到了换行符\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
)

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

<?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 ......

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 正则表达式是用来匹配字符串模式的工具,其限定修饰符是指用来限制模式匹配次数的特殊字符。在Java正则表达式的限定修饰符包括: 1. *:表示匹配前面的元素0次或多次。 2. +:表示匹配前面的元素1次或多次。 3. ?:表示匹配前面的元素0次或1次。 4. {n}:表示匹配前面的元素恰好n次。 5. {n,}:表示匹配前面的元素至少n次。 6. {n,m}:表示匹配前面的元素至少n次,但不超过m次。 例如,如果我们要匹配一个字符串,使其以字母a开头,后面跟着0个或多个字母b,那么我们可以使用正则表达式:a*b*。 另外需要注意的是,这些限定修饰符默认是“贪婪”的,也就是尽可能多地匹配符合条件的字符串。如果需要改为“懒惰”模式,可以在修饰符后面加上“?”,例如:*?、+?、??、{n}?、{n,}?、{n,m}?。 ### 回答2: Java正则表达式的限定修饰符在匹配字符串时可以表示某个字符出现的次数或位置的限定条件,它们是一种非常强大的功能。 常见的限定修饰符有: 1. \* :匹配零次或多次出现的前面的字符,例如 "zo*"可以匹配 "z"和 "zoo"。 2. + :匹配一次或多次出现的前面的字符,例如 "zo+"可以匹配 "zo"和 "zoo",但不能匹配 "z"。 3. ? :匹配零次或一次出现的前面的字符,例如 "do(es)?"可以匹配 "does"和 "doesnot"。 除此之外,还有一些比较特殊的限定修饰符,如: 1. {n} :匹配前面的字符恰好出现 n次,例如 "zo{2}"可以匹配 "zoo",但不能匹配 "zo"或 "zoatt"。 2. {n,} :匹配前面的字符至少出现 n次,例如 "zo{2,}"可以匹配 "zoo"和 "zoatt",但不会匹配 "z"。 3. {n,m} :匹配前面的字符至少出现 n次,但不超过 m次,例如 "zo{1,2}"可以匹配 "zo"和 "zoo",但不会匹配 "z"或 "zoatt"。 除了以上三个,还可以通过同时使用多个限定修饰符来匹配不同的字符串,如: 1. "zo*"可以匹配 "z","zo","zoo"等等。 2. "zo{2,3}"可以匹配 "zoo"和 "zooa",但不能匹配 "zo"或 "zoatt"。 正则表达式的限定修饰符可以让你更加灵活地匹配需要的字符串,它是Java字符串处理非常重要的一部分,掌握好这些知识可以大大提升你对字符串的处理能力。 ### 回答3: 正则表达式是我们经常使用的一种工具,可以通过表达式匹配对应的文本或字符集。在Java,字符串也支持正则表达式的应用,可以利用正则表达式对字符串进行匹配、替换、分割等操作。正则表达式的限定修饰符则是正则表达式的一种语法,用来指定正则表达式匹配的数量或范围。 正则表达式的限定修饰符有以下几种: 1. *(星号):表示匹配前面的字符出现0次或多次。 例如:正则表达式“a*b”可以匹配到“b”、“ab”、“aab”、“aaab”等字符串。 2. +(加号):表示匹配前面的字符出现1次或多次。 例如:正则表达式“a+b”可以匹配到“ab”、“aab”、“aaab”等字符串,但不能匹配到“b”这样的字符串。 3. ?(问号):表示匹配前面的字符出现0次或1次。 例如:正则表达式“a?b”可以匹配到“b”、“ab”这样的字符串。 4. {n}:表示匹配前面的字符刚好出现n次。 例如:正则表达式“a{2}b”可以匹配到“aab”这样的字符串。 5. {n,}:表示匹配前面的字符至少出现n次。 例如:正则表达式“a{2,}b”可以匹配到“aab”、“aaab”等字符串。 6. {n,m}:表示匹配前面的字符出现n到m次。 例如:正则表达式“a{2,4}b”可以匹配到“aab”、“aaab”、“aaaab”这样的字符串。 除了以上几种限定修饰符外,还可以使用“|”(或)符号来匹配多个选择,使用“()”来对正则表达式进行分组。 在Java,可以利用String类的matches()方法来进行正则表达式的匹配。matches()方法接收一个正则表达式作为参数,如果字符串符合该正则表达式,则返回true;否则返回false。例如: String str = "abc123"; boolean result = str.matches("[a-z]{3}[0-9]{3}"); // result会被赋值为true,因为str符合正则表达式[a-z]{3}[0-9]{3} 正则表达式的限定修饰符正则表达式的重要组成部分,掌握了限定修饰符,就能更好地利用正则表达式进行字符串的处理。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

迹忆客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值