正则表达式 分组 零宽断言

分组

import re
a = '123.123.123.aaa.aaa.aaa'
reg = '(\d{3})(.\\1){2}.(\w{3})(.\\3){2}'
res = re.search(reg,a)
print(res)   # <re.Match object; span=(0, 23), match='123.123.123.aaa.aaa.aaa'>

引用分组
上例中\\1代表引用第一个分组\d{3}\\3代表引用第三个分组\w{3}

import re
a = '123.234.345.456'
b = '123.123.123.123'
reg = '(\d{1,3})(.\\1){3}'
resa = re.search(reg,a)
resb = re.search(reg,b)
print(resa,'\n',resb)
'''输出
None 
 <re.Match object; span=(0, 15), match='123.123.123.123'>
 '''

引用文本内容
由上例,后向引用,引用的仅仅是文本内容,而不是正则表达式
也就是说,组中的内容一旦匹配成功,后向引用,引用的就是匹配成功后的内容,引用的是结果,而不是表达式。

分组编号规律
无论括号如何嵌套,分组的编号都是根据开括号出现的顺序来计数的;开括号是从左至右数起第多少个开括号,分组编号就是多少。如下图:
在这里插入图片描述

断言

指明某个字符串前边或者后边,将会出现满足某种规律的字符串

如:(?<=<title>).*(?=</title>) 或者 (?<=<(title)>).*(?=</\\1>)

a = '<title>这里是标题内容</title>'
reg = '(?<=<title>).*(?=</title>)'
# 或
# reg = '(?<=<(title)>).*(?=</\\1>)'
resa = re.search(reg,a)
print(resa)    # <re.Match object; span=(7, 14), match='这里是标题内容'>
  • (?=pattern) 零宽正向先行断言(zero-width positive lookahead assertion)
    它断言自身出现位置的后边能匹配表达式exp
  • (?!pattern) 零宽负向先行断言(zero-width negative lookahead assertion)
    它断言自身出现位置的后边不能匹配表达式exp
  • (?<=pattern) 零宽正向后行断言(zero-width positive lookbehind assertion)
    它断言自身出现位置的左边能匹配表达式exp
  • (?<!pattern) 零宽负向后行断言(zero-width negative lookbehind assertion)
    它断言自身出现位置的左边不能匹配表达式exp

:匹配 中国人的“人”而不匹配 外国人的“人”

b = '外国人中国人'
reg1 = '(?<!外国)人'
reg2 = '人'
res1 = re.search(reg1,b)
res2 = re.search(reg2,b)
print(res1,'\n',res2)
'''输出
<re.Match object; span=(5, 6), match='人'> 
 <re.Match object; span=(2, 3), match='人'>
'''

:匹配 中国制造的“中国”

b = '中国生产中国制造'
reg1 = '中国(?!生产)'
res1 = re.search(reg1,b)
print(res1)
'''输出
<re.Match object; span=(4, 6), match='中国'>
'''

如同^代表开头,$代表结尾,\b代表单词边界一样,先行断言和后行断言也有类似的作用,它们只匹配某些位置,在匹配过程中,不占用字符,所以被称为“零宽”。所谓位置,是指字符串中(每行)第一个字符的左边、最后一个字符的右边以及相邻字符的中间(假设文字方向是头左尾右)

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值