正则表达式学习笔记(三)模式修饰符与其他量词

本文深入探讨了正则表达式的高级应用,包括模式修饰符的使用,如不区分大小写匹配,以及量词的两种类型:忽略优先和占有优先。通过实例讲解如何提升正则表达式的效率和灵活性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天我们接着学习一些正则表达式高级的话题。

模式修饰符

当我们做字符串查找的时候,有很多情况我们都需要忽略字符串大小写,但是不是所有的编辑器都像grep一样提供简单的 -i 选项,比如,当我们在使用Notepad++的时候,又或者当我们在.Net,Java里面使用的时候,我们需要忽略大小写匹配正则表达式,有没有什么办法呢?

答案是肯定的,这个时候我们就需要用到模式修饰符。常用的模式修饰符有如下几种:

字符模式
i不区分大小写
x宽松排列和注释模式
s点号通配模式
m增强的行锚点模式

其中我们最可能用上的就是不区分大小写的模式修饰符,使用语法(?i)打开模式让不区分大小写开始工作,之后如果不需要不区分大小写,使用语法(?-i)关闭模式,让我们看一个例子。

现有一个目标字符串,可能是Hello, 也可能是hello, 甚至还可能是HELLO, 要想很轻松的匹配,我们最好的选择是使用模式(?i)hello去进行匹配,否则,我们就只有使用一个很丑陋的模式Hello|hello|HELLO...。进一步说,如果目标字符串是Hello World, 那么模式(?i)hello\s+world匹配,但是(?i)hello(?-i)\s+world却无法匹配,因为过早的关掉了不区分大小写的模式。

 

忽略优先量词

考虑量词,*,?,+和{min, max},这些量词的本性是匹配优先,即贪婪匹配,比如.*可以吃掉目标字符串的一切。在有些情况下这种行为是我们乐于见到的,但是在一些情况下,这种特性会造成极大的性能问题,考虑使用.*a来匹配目标字符串abcdefghj..xyz,在NFA引擎下面这个匹配的性能会低到令人发指(原因等我们讲到正则表达式引擎的时候会说明)。所以偶尔我们也希望量词能改改它们的秉性,仅仅只匹配最低程度即可,总结来看:

目标文本量词效果忽略优先量词忽略优先效果
aaaba*匹配aaaa*?不匹配任何东西
aaaba?匹配aa??不匹配任何东西
aaaba+匹配aaaa+?匹配a
aaaba{2,3}匹配aaaa{2,3}?匹配aa

从上面我们可以看出,在量词后面加?使量词变为忽略优先量词,忽略优先量词仅仅匹配满足自己最小要求的部分,当然,这是在不影响整个字符串的匹配成功的前提下,如果字符串匹配要求忽略优先量词“从大局出发”,必须匹配更多的内容,量词也是义不容辞的。比如,用a*?b匹配aaab,为了匹配成功,a*?也会匹配aaa。

 

占有优先量词

还有一种量词叫占有优先量词,在量词 *, ?, + 和 {min,max}后面添加+即可,占有优先量词最基本的特征就是,他一旦匹配成功,就不会改变,哪怕造成正规字符串匹配失误也在所不惜。比如,用.*b来匹配aaab是完全没有问题的,前面.*先匹配整个字符串,后面发现有个b需要匹配,.*会从自己已有的匹配中退出一部分字符来尝试满足这个条件,当然,这样的结果是皆大欢喜。另一方面,如果这里我们使用的是模式.*+b来匹配,那么这个匹配会失败,因为.*+是占有优先,不会为了整个字符串的匹配与否退出字符。

占有优先量词很像固化分组(?>),都是匹配之后就不会变化,在没有完全熟悉正则表达式的原理和引擎之前,建议不要轻易使用,否则会给自己带来不必要的麻烦。

接下来我们会学习正则表达式的引擎,这是正则表达式的核心,了解引擎以及匹配原理之后,我们在使用正则表达式的时候就会更加得心应手,敬请期待!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值