python正则表达式

前向匹配和后向匹配

术语介绍
模式正向向后查找 positive look-behind(?<=)
正向向前查找positive look-ahead(?=)
负向向后查找negative look-behind(?<!)
负向向前查找negative look-ahead(?!)
正向和负向指的分别是 出现则匹配 和 不出现则匹配

1. (?<=[pattern])和 (?<![pattern])

  • 功能
    匹配[pattern]的内容,但在结果中并不会返回这个子模式
  • 用法
    (?<=[pattern])是放在待匹配正则表达式 之前的,(?=[pattern])是放在待匹配正则表达式之后; 相关用法如下所示
正则表达式是否正确
(?<=[pattern1])[pattern2](?=[pattern3])
(?=[pattern1])[pattern2](?<=[pattern3])
[pattern4](?<=[pattern1])[pattern2](?=[pattern3])
[pattern4](?<=[pattern1])[pattern2](?=[pattern3])[pattern5]
(?<=[pattern1])[pattern2]
[pattern2](?=[pattern1])

要匹配的正则表达式在(?<=[pattern])后面,所以匹配的时候是往后看的,所以(?<=[pattern])就叫look-behind。需要注意(?<=[pattern])里的子模式pattern的宽度一定要确定,也就是子模式中不能出现*?+等模式

  • 实验
    识别出下面句子里所有的姓氏
Dr.David Jone, Ophthalmology, Ms.Cindy Harriman, Registry, Mr.Chester Addams, Mortuary, Dr.Hawkeye Pierce, Surgery

每个姓氏前面都是空格,后面都是逗号,因此可以写成如下形式

import re
pattern=re.compile(r'(?<=\s)([A-Za-z]*)(?=,)')
string = "Dr.David Jone, Ophthalmology, Ms.Cindy Harriman, Registry, Mr.Chester Addams, Mortuary, Dr.Hawkeye Pierce, Surgery"
res = pattern.findall(string)
print(res)

输出结果

['Jone', 'Ophthalmology', 'Harriman', 'Registry', 'Addams', 'Mortuary', 'Pierce']

2. (?<![pattern])和(?![pattern])

  • 功能
    如果没出现[pattern]的内容就匹配,但在结果中并不会返回这个子模式
  • 用法
    (?<![pattern])是放在待匹配正则表达式之前的,(?![pattern])是放在待匹配正则表达式之后

3. 非捕获组(?:[pattern])

  • 功能
    匹配[pattern],但不会记录这个组

  • 实验

import re
s = 'Cake is better than potato'
pattern = re.compile(r'(?:is\s)better(\sthan)')
print("out1:", pattern.search(s).group(0))
print("out2:", pattern.search(s).group(1)) 

输出

out1: is better than
out2:  than

Match对象的group(num/name)方法返回的是对应组的内容,子模式序号从1开始。group(0)返回的是整个模式的匹配内容(is better than),而group(1)返回的是第1个子模式的内容( than)
这里可以发现第1个子模式对应的是(\sthan)而不是(?:is\s),也就是说(?:is\s)这个组未被捕获(没有被记录)

前向查找和非捕获组的区别

positive look-ahead(正向向前查找) (?=[pattern])positive look-behind(正向向后查找) (?<=[pattern]) 是 出现[pattern]则匹配,但并不返回该子模式匹配的内容,它们和(?:[pattern])有什么区别呢?

import re
s = 'Cake is better than potato'
pattern1 = re.compile(r'(?:is\s)better(\sthan)')
pattern2 = re.compile(r'(?<=is\s)better(\sthan)')
print("p1g0:", pattern1.search(s).group(0))
print("p1g1:", pattern1.search(s).group(1))
print("p2g0:", pattern2.search(s).group(0))
print("p2g1:", pattern2.search(s).group(1))

输出

p1g0: is better than
p1g1:  than
p2g0: better than
p2g1:  than

结论

  • (?<=[pattern])(?=[pattern])是匹配到了[pattern]不会返回、亦不会记录(捕获)[pattern]子模式,所以在上面例子中整个模式的匹配结果中没有 is空格。
  • (?:[pattern])是匹配到了[pattern]会返回,但不会记录(捕获)[pattern]子模式,所以在上面例子中整个的匹配结果中有 is空格。
  • (?:[pattern])(?<=[pattern])(?=[pattern]) 的共同点是 都不会记录[pattern]子模式(子组),所以上面例子中group(1)找到的第1个组的内容是(\sthan)匹配到的空格than

参考

Python正则表达式细节小记

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python正则表达式是一种强大的字符串处理工具,它可以用于在文本中查找、替换和提取特定模式的字符串。在Python中使用正则表达式,需要先导入`re`模块。 下面是一个简单的示例代码,演示了如何使用正则表达式在字符串中匹配特定的模式: ```python import re # 定义一个待匹配的字符串 string = "Hello, my email address is example@example.com" # 定义一个正则表达式模式,用于匹配邮箱地址 pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b' # 使用re模块的findall()方法进行匹配 matches = re.findall(pattern, string) # 输出匹配的结果 print(matches) ``` 运行以上代码,输出结果会是`['example@example.com']`,即匹配到了字符串中的邮箱地址。 在正则表达式中,可以使用一些特殊字符和元字符来构建匹配模式。例如,`r'\b'`表示单词边界,`[A-Za-z0-9._%+-]`表示匹配字母、数字、点、下划线、百分号、加号和减号等字符。 除了匹配字符,还可以使用一些特殊的元字符来表示数量和位置。例如,`+`表示前面的字符出现一次或多次,`*`表示前面的字符出现零次或多次,`{2,}`表示前面的字符出现至少两次。 以上只是简单介绍了Python正则表达式的基本用法,实际上正则表达式还有很多高级用法和特性。你可以参考Python官方文档中关于`re`模块的详细说明来深入学习和理解正则表达式的使用方法。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值