正则表达式进阶

一、分组

(A)((B)C)
各个group如下:
0 表示(A)((B)C),也就是匹配的全部
1 表示第一个左括号所包括的内容,即(A)
2 表示第二个左括号所包括的内容,即((B)C)
3 表示第三个左括号所包括的内容,即(B)

import re
s="ABC"
res=re.findall('(.((.).))',s)
print(res) #[('ABC', 'BC', 'B')]

二、.所表示的任意字符不包括换行符

import re

s = """weiyinfu is great
haha yes
"""
x = re.search('is.*?yes', s)
print(x.group())

运行这段代码会报错,因为x为None,正则表达式最多匹配一行

如果有回车符,显示会有问题
其实匹配正确,只是显示错误,这让人误以为正则表达式写错了。
回车符的作用就是删除本行并把光标移动到行首,在windows下体现不出这一点,在linux下才能体现出来。

import re

s = "weiyinfu is great 
 haha yes"
x = re.search('is.*?yes', s)
print(x.group())#输出为 haha yes

三、脱壳处理

search和findall默认匹配第一个左括号对应的内容

  • 如果正则表达式中仅有一对括号,那么直接返回这对括号内的内容,也就是直接返回一个字符串
  • 如果正则表达式中包含多对括号,那么返回一个字符串元组
  • Python中的正则表达式会自动把仅包含一个字符串的元组改写为字符串类型,此操作称之为脱壳
import re

s = "11321323"
res = re.findall('(d+?)2', s)  # ['113', '13']
print(res)
print(re.search("(d+?)2", s).groups())  # ('113',)
print(re.search("(d+?)2", s).group(0))  # 1132
print(re.findall("((d+?)2)", s))  # [('1132', '113'), ('132', '13')]
print(re.findall("((d+?))2", s))  # [('113', '113'), ('13', '13')]

三、反向引用

给定一个数字串,找出把2夹在中间的全部数字,例如323,121等。

import re

s = "11321323"
print(re.findall('(d)2\1', s))  # ['3']
print(re.findall(r'(d)21', s))  # ['3']
print(re.findall(r'(d)2\1', s))  # [],画蛇添足

四、非捕获组

默认情况下,每个左括号都对应一个group。使用非捕获组,可以让左括号不参与组的计数。

import re

s = "ABC"
print(re.findall('(.((.).))', s))  # [('ABC', 'BC', 'B')]
print(re.findall('(?:.((.).))', s))  # [('BC', 'B')]
print(re.findall('(?:.(?:(.).))', s))  # ['B']

五、零宽断言

零宽断言一共有四种:(前+后)*(等+不等)

  • (?=X) 后面必须是X
  • (?!X) 后面必须不是X
  • (?<=X) 前面必须是X
  • (?<!X) 前面必须不是X

其中X可以是任意正则表达式。
有一个随机数字串,找出包含在0,1之间的数字串,要求:

  1. 0前面不能是2
  2. 1后面不能是3
  3. 0、1之间指0d+1这种形式
import re

s = "1023120513"
print(re.findall("(?<=[^2]0)d+?(?=1[^3])", s))

直接输出'23',零宽断言的好处在于:避免了通过group进一步摘取内容。

六、模式开关

格式:(?imsx-imsx:Pattern)
例(1):(?i)ab(?-i)cd可匹配abcd,Abcd,ABcd,aBcd
(?i)开启忽略大小写功能
(?-i)开启大小写敏感开关

例(2):(?i:a)b,可匹配ab和Ab

七、贪婪模式和非贪婪模式

d+?可匹配尽量少的d,此即为非贪婪模式。
d+可匹配尽量多的d,这是默认情况下,此为贪婪模式

八、JavaScript中的正则表达式

js获取正则表达式有如下两种方式:

  • array=str.match(regex)
  • array=regex.exec(str)

得到的array是字符串数组,表示各个group,有两种获取分组的方式

  • array[0],array[1],这是推荐方式
  • RegExp.$1,RegExp.$2,通过全局变量来获取,这种方式正常运行的前提是:JavaScript是单线程的,不会出现并发冲突。这种方式应该尽量避免使用。

regex.test(str)可以以bool值的形式获取str中是否包含regex。

原文地址:https://www.cnblogs.com/weiyinfu/p/7149617.html