正则表达式学习笔记(三)--------分组语法、贪婪与懒惰

五、分组语法

捕获语法

(exp) 匹配exp,并捕获文本到自动命名的组里;
(?exp) 匹配exp,并捕获文本到名称为name的组里,也可以写成(?'name’exp);
(?:exp) 匹配exp,不捕获匹配的文本,也不给此分组分配组号;

在之前表示ip地址时候已经涉及过分组的使用,即: ==(\d{1,3}.){3}\d{1,3} == ,这是第一种的用法,即是使用了自动命名的组。默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。比如说是: ((\d){3}\d(\d){5}){2} ,在这种情况下,最外层的括号,即重复两次的分组为1,往内重复三次的括号为2组,剩下的组号为3。
并且额外的, 需注意
1、分组0对应整个正则表达式
2、从微观来看,组号分配过程是要从左向右扫描两遍的:第一遍只给未命名组分配,第二遍只给命名组分配--因此所有命名组的组号都大于未命名的组号
3、可以使用(?:exp)这样的语法来剥夺一个分组对组号分配的参与权.

后向引用

后向引用用于重复搜索前面某个分组匹配的文本。比如: \b(\w+)\b\s+\1\b ,‘()’内的内容默认为分组1,而之后的‘\1’又是对该内容的再次引用,这段表达式的作用是,用来匹配一些重复的单词,‘\1’等于(\w+)的再次引用。

(?exp)/(?'name’exp)

在(exp)的的基础上,可以在左括号开始处赋予分组名字,类似于C语言中的变量命名,而在后向引用中需要使用 \k<name>或者 \k'name'

(?:exp)

(?:exp)不会改变正则表达式的处理方式,只是这样的组匹配的内容不会像前两种那样被捕获到某个组里面,也不会拥有组号。也就是说无法被后向引用。。。。。。暂时还不知道这样做的意义在什么地方。

零宽断言

通俗理解就是指定某个位置,类似于\b,$,^。具体指定的位置要看满足什么条件(即断言):
(?=exp):条件是: 自身出现的位置的后面能匹配表达式exp 。例如: \b\w+(?=ing\b) ,匹配以ing结尾的单词的前面部分(除了ing以外的部分),如查找I’m singing while you’re dancing.时,它会匹配sing和danc。可以将‘?=’理解成被sing和danc替代;
(?<=exp):条件是: 自身出现的位置的前面能匹配表达式exp ,匹配的位置刚好是与上面的相反。

负向零宽断言

(?!exp):条件是: 此位置的后面不能匹配表达式exp ,例如: \b((?!abc)\w)+\b 匹配不包含连续字符串abc的单词。
(?<!exp): 条件是: 断言此位置的前面不能匹配表达式exp

注释方法

()的另一种使用方式,即是注释使用,具体用法是:(?#notes),例如在之前的ip地址表达式中,由于太长可能不利于我们去理解具体含义,可以在书写的时候增加注释:
((25[0-5]|2[0-4]\d|[01]?\d\d?).){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)
注释后:
((25[0-5](?#250-255)|2[0-4]\d(?#200-249)|[01]?\d\d?(?#0-199)).){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)
或者可直接在表达式中插入#notes,但是缺点和python中的是一样的,即#之后的内容都将被注释掉。

六、贪婪与懒惰

贪婪

顾名思义,贪婪是指:当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。比如表达式a.*b,用它来搜索aabab的话,它会匹配整个字符串aabab,即贪婪匹配。

懒惰

有时,我们更需要匹配尽可能少的字符,此时在前面给出的限定符后面加上一个 ,就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复。比如在之前的表达式上修改为:a.*?b,同样在aabab上应用,则它会匹配aab(第一到第三个字符)和ab(第四到第五个字符)。
注意 :不先匹配ab而是先匹配aab的原因: 最先开始的匹配拥有最高的优先权

发布了13 篇原创文章 · 获赞 0 · 访问量 354

猜你喜欢

转载自blog.csdn.net/xiao_xiao_lan/article/details/105267802