正则表达式 (?:pattern)(?=pattern)

  (?:pattern)(?=pattern)、(?=pattern)、(?!pattern)、(?<=pattern)和(?<!pattern)

(?:pattern)

pattern:表示表达式

# 1. (?:pattern)
"""
()表示捕获分组,()会把每个分组里的匹配的值保存起来,从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推
(?:)表示非捕获分组,和捕获分组唯一的区别在于,非捕获分组匹配的值不会保存起来
[\u4e00-\u9fa5] 中文
"""
m = re.search("(\d+)([\u4e00-\u9fa5]*)([a-z]*)\s(\d*)", "afa455阿登哥love 520")
print(m) # '455阿登哥love
# re.Match对象可以调用group()方法
print(m.group(0, 1, 2, 3, 4)) #  ('455阿登哥love 520', '455', '阿登哥', 'love', '520')

# 在分组里使用?:

m = re.search("(?:\d+)(?:[\u4e00-\u9fa5]*)([a-z]*)\s(\d*)", "afa455阿登哥love 520")
print(m.group(0, 1, 2)) # ('455阿登哥love 520', 'love', '520')

# 27行 对比22行代码返回结果 455 和 阿登哥 并没有保存下来

# --------------findall() (?:pattern) 单个情况可以匹配到表达式全部内容----------------

print(re.findall('(?:ab)+123','ababab123')) #findall的结果不是匹配的全部内容,而是组内的内容,?:可以让结果为匹配的全部内容 ['ababab123']
print(re.findall('href="(.*?)"','<a href="http://www.baidu.com">点击</a>'))#['http://www.baidu.com']
print(re.findall('href="(?:.*?)"','<a href="http://www.baidu.com">点击</a>'))#['href="http://www.baidu.com"']

 (?=pattern)、(?!pattern)、(?<=pattern)和(?<!pattern)

import re

# (?=pattern) 简单说,以 xxx(?=pattern)为例,就是捕获以pattern结尾的内容xxx


print(re.findall("Windows(?=95|98|NT|2000)", "Windows2000_WindowsNT_WindowsXP")) # ['Windows', 'Windows']


# (?!pattern) 简单说,以 xxx(?!pattern)为例,就是捕获不以pattern结尾的内容xxx

print(re.findall("Windows(?!95|98|NT|2000)", "Windows2000_WindowsNT_WindowsXP")) # ['Windows']


# (?<=pattern) 简单说,以(?<=pattern)xxx为例,就是捕获以pattern开头的内容xxx

print(re.findall("(?<=2000)year", "abc2000year444")) #  ['year']

# (?<!pattern) 简单说,以(?<!pattern)xxx为例,就是捕获不以pattern开头的内容xxx。

print(re.findall("(?<!2000)year", "032year444")) #  ['year']


百度网上的一些资料

# ----------------------------------------------------------
print(re.findall("egon(?=100|N)(?=N)N123","egonN123"))    # ['egonN123']

位置:   0    1    2    3    4    5    6     7
字符串:e    g    o    n    N    1    2    3


分析:
步骤1、正则表达式egon匹配到了字符串的位置3

然后连续进行两次断言匹配
步骤2、(?=100|N)从位置3作为起始匹配位置4的字符是否100或者N
步骤3、2成功后,继续匹配(?=N),因为?=patter不会吃字符,所以此时会重新回到步骤1所在位置3,然后继续匹配,匹配成功

步骤4、从位置3开始匹配N123


思考下述输出结果,为何会不同???:
print(re.findall("egon(?=100|N)(?=N)N123", "egonN123"))
print(re.findall("egon(?=100|N)(?=N)123", "egonN123")) 从 3位置匹配 后面没匹配到123 所以返回为空列表


#-------------------------------------------------------------

 

介绍

(pattern) : 匹配 pattern 并获取这一匹配,所获取的匹配可以从产生的 Matches 集合得到。
(?:pattern) :匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。
(?=pattern) :正向预查,在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。

共同点

(?:pattern) 与 (?=pattern)都匹配pattern,但不会把pattern结果放到Matches的集合中,即Matcher.group()不会匹配到(?;pattern)与(?=pattern)

区别

(?:pattern) 匹配得到的结果包含pattern,(?=pattern) 则不包含。如:
对字符串:"industry abc"的匹配结果:
industr(?:y|ies) ---> "industry"
industr(?=y|ies) ---> "industr"
是否消耗字符:
(?:pattern) 消耗字符,下一字符匹配会从已匹配后的位置开始。
(?=pattern) 不消耗字符,下一字符匹配会从预查之前的位置开始。

即后者只预查,不移动匹配指针。如:


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值