正则表达式组与断言

正则表达式组与断言

​ 正则表达式处理的对象是字符串,或者抽象地说,是一个对象序列,若要为字符串设定多个匹配规则并分别使用的话,那么使用正则表达式分组是更好的选择,这也体现了正则表达式的灵活与高效。

分组

​ 分组就是用一对圆括号“()”括起来的正则表达式,匹配出的内容就表示一个分组。从正则表达式的左边开始看,看到的第一个左括号“(”表示第一个分组,第二个表示第二个分组,依次类推,需要注意的是,有一个隐含的全局分组(0分组),就是整个正则表达式。

​ 分完组以后,要想获得某个分组的内容,直接使用group(num)和groups()函数去直接提取就行。

​ group(0) 是获取取得的字符串整体,group(1)是取出括号里面要匹配的分组内容,groups() 的功能就是分别取出所有的要匹配的值,不包含group(0)。

import re

a: str = "123abc456"
print(re.search("([0-9]*)([a-z]*)([0-9]*)", a).group(0))  # 123abc456
print(re.search("([0-9]*)([a-z]*)([0-9]*)", a).group(1))  # 123
print(re.search("([0-9]*)([a-z]*)([0-9]*)", a).group(2))  # abc
print(re.search("([0-9]*)([a-z]*)([0-9]*)", a).group(3))  # 456
print(re.search("([0-9]*)([a-z]*)([0-9]*)", a).groups())  # ('123', 'abc', '456')

断言

​ 断言是判断当前位置的前后是否匹配,但是不消耗任何字符,只用于匹配位置,而不是文本内容本身,这种结构就是断言。在匹配过程中,不占用字符,所以被称为**“零宽”**。

​ 正则表达式的先行断言和后行断言一共有 4 种形式:

(?=pattern) 零宽正向先行断言(zero-width positive lookahead assertion)

(?!pattern) 零宽负向先行断言(zero-width negative lookahead assertion)

(?<=pattern) 零宽正向后行断言(zero-width positive lookbehind assertion)

(?<!pattern) 零宽负向后行断言(zero-width negative lookbehind assertion)

​ 这里面的 pattern 是一个正则表达式。

对于这 4 个断言的理解,可以从两个方面入手:

1、关于先行(lookahead)和后行(lookbehind):正则表达式引擎在执行字符串和表达式匹配时,会从前到后连续扫描字符串中的字符,设想有一个扫描指针指向字符边界处并随匹配过程移动。先行断言,是当扫描指针位于某处时,引擎会尝试匹配指针还未扫过的字符,先于指针到达该字符,故称为先行。后行断言,引擎会尝试匹配指针已扫过的字符,后于指针到达该字符,故称为后行。

2、关于正向(positive)和负向(negative):正向就表示匹配括号中的表达式,负向表示不匹配。

import re

b: str = "ABC1230321CBA"
print(re.search("2(?=3)", b))  # <re.Match object; span=(4, 5), match='2'>
print(re.search("2(?!3)", b))  # <re.Match object; span=(8, 9), match='2'>
print(re.search("(?<=A)B", b))  # <re.Match object; span=(1, 2), match='B'>
print(re.search("(?<!A)B", b))  # <re.Match object; span=(11, 12), match='B'>
  • (?=pattern) 正向先行断言,代表字符串中的一个位置,紧接该位置之后的字符序列能够匹配 pattern。
print(re.search("2(?=3)", b))  
# <re.Match object; span=(4, 5), match='2'>
  • (?!pattern) 负向先行断言,代表字符串中的一个位置,紧接该位置之后的字符序列不能匹配 pattern。
print(re.search("2(?!3)", b))  
# <re.Match object; span=(8, 9), match='2'>
  • (?<=pattern) 正向后行断言,代表字符串中的一个位置,紧接该位置之前的字符序列能够匹配 pattern。
print(re.search("(?<=A)B", b))  
# <re.Match object; span=(1, 2), match='B'>
  • (?<!pattern) 负向后行断言,代表字符串中的一个位置,紧接该位置之前的字符序列不能匹配 pattern。
print(re.search("(?<!A)B", b))  
# <re.Match object; span=(11, 12), match='B'>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值