python之正则表达式及re模块
1 正则表达式
字符串处理是编程中常遇见的问题,如:字符串的增、删、改、查等,其首要问题是字符串的匹配,正则表达式正是用来解决这个问题的。
正则表达式,又称规则表达式(Regular Expression,在代码中常简写为regex、regexp或re)
给定一个正则表达式和一个字符串,可以达到如下的目的:
-
判断给定的字符串是否符合正则表达式的过滤逻辑(称作“匹配”);
-
可以通过正则表达式,从字符串中获取我们想要的特定部分。
正则表达式语法:
见参考1,2
-
字符
字符 描述 等价于 . 匹配除换行符以外的任意字符 \w 匹配字母、数字、下划线 [A-Za-z0-9_] \W 匹配任何非单词字符(匹配非字母、非数字、非下划线) [^A-Za-z0-9_] \d 数字,匹配一个数字字符 [0-9] \D 非数字,匹配一个非数字字符 [^0-9] \s 空白, 匹配任何空白字符,包括空格、制表符等。 \S 非空白,匹配任意不是空白符的字符 \t 匹配一个水平制表符tab \b 匹配单词的开始或结束 \B 匹配不是单词开头或结束的位置 [^x] 匹配除了x以外的任意字符 -
数量表示
字符 描述 等价于 * (前面的字符)重复0次或多次 + (前面的字符)重复1次或多次 ? (前面的字符)重复0次或1次 匹配前面的表达式n个 (前面的字符)重复n次或更多次(至少重复n次) (前面的字符)重复n到m次 -
范围集合
字符 描述 x|y 匹配 x 或 y, | 的算符优先级较低 [xyz] 字符集合,匹配包含的任意一个字符 [^xyz] 字符集取反,匹配未包含的任意字符 [a-z] 字符范围,匹配指定范围内的任意字符,可以连写: [a-zA-Z0-9] [^a-z] 负值字符范围,匹配任何不在指定范围内的任意字符 -
边界字符
字符 描述 ^ 匹配输入字符串开头位置 $ 匹配输入字符串结尾的位置 \b 匹配单词的开始或结束比如 Sheep\b
可以匹配CodeSheep
末尾的Sheep
,不能匹配CodeSheepCode
中的Sheep
\B 匹配不是单词开头或结束的位置比如 Code\B
可以匹配HelloCodeSheep
中的Code
,不能匹配HelloCode
中的Code
。 -
分组和引用
字符 描述 (expression) 分组。匹配括号里的整个表达式。 (?:expression) 非捕获分组。匹配括号里的整个字符串但不获取匹配结果,不进行存储供以后使用 \num 对前面所匹配分组的引用。比如 (\d)\1
可以匹配两个相同的数字,(Code)(Sheep)\1\2
则可以匹配CodeSheepCodeSheep
。 -
预查断言
字符 描述 (?=) 正向预查。比如 Code(?=Sheep)
能匹配CodeSheep
中的Code
,但不能匹配CodePig
中的Code
。(?!) 正向否定预查。比如 Code(?!Sheep)
不能匹配CodeSheep
中的Code
,但能匹配CodePig
中的Code
。(?<=) 反向预查。比如 (?<=Code)Sheep
能匹配CodeSheep
中的Sheep
,但不能匹配ReadSheep
中的Sheep
。(?<!) 反向否定预查。比如 (?<!Code)Sheep
不能匹配CodeSheep
中的Sheep
,但能匹配ReadSheep
中的Sheep
。 -
模式修正符
字符 描述 i (ignore case) 不区分大小写 m (mulitipleline)多行搜索(将字符串视为多行,不管是哪行都能匹配) s (singleline) 将字符串视为单行,转义回车换行符作为普通字符 g (global) 全局匹配
2 python中的Re模块
2.1 字符串的查找方法
先说一下不import re模块时,python字符串也有一些字符串匹配方法,只不过功能较简单,不能进行复杂的字符串匹配。
字符串方法 | 描述 |
---|---|
str.startswith(str1) | 检查字符串是否以str1开头 |
str.endswith(str1) | 检查字符串是否以str1结尾 |
str.find(str1, start=0, end=len(str)) | 检查str1是否在str中,只检查str[star, end]范围内 |
str.rfind() | rfind和find()方法类似,不过是从右边开始查找 |
str.index(str1, start=0, end=len(str1)) | index和find()方法类似,只不过str1在str中不存在就会报错 |
str.rindex() | rindex和index()方法类似,不过是从右边开始查找 |
示例:
if __name__ == '__main__':
string = "just a test"
# startswith 方法,检查字符串是否以str1开头
res = string.startswith('jus')
print(f'startswith res = {res}') # 结果: res = True
# endswith 方法,检查字符串是否以str1开头
res = string.endswith('est')
print(f'endswith res = {res}') # 结果: res = True
# find 方法
res = string.find('a t')
print(f'find res = {res}') # 结果: res = 5
# 字符串 0 - 5 中没有'a t',应返回-1
res = string.find('a t', 0, 5)
print(f'find strip res = {res}') # 结果: res = -1
# index方法,检测某个子串是否包含在这个字符串中,
# 如果在返回这个子串开始的位置下标,否则则报异常
res = string.index('a t')
print(f'index res = {res}') # 结果: res = 5
# 不存在报异常
res = string.index('a t', 0, 5)
print(f'index strip res = {res}')# 不存在报错
# rfind与rindex 从右向左侧找
res = string.rfind('est')
print(f'rfind res = {res}') # 结果:res = 8,还是从左到右数
res = string.rindex('est')
print(f'rindex res = {res}') # 结果:res = 8
2.2 python中的re模块
python中提供re(正则表达式)模块,用来匹配处理字符串。
re方法 | 描述 |
---|---|
re.match | 从字符串起始位置匹配 |
re.search | 扫描整个字符串,并返回第一个成功的匹配 |
re.findall | 在字符串中找到正则表达式所匹配的所有子串,并返回一个列表 (match 和 search 是匹配一次,findall 匹配所有) |
re.finditer | finditer和 findall 类似,在字符串中找到正则表达式所匹配的所有子串, 并把它们作为一个迭代器返回。 |
re.compile | compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象, 供 match() 、search()、findall 这些函数使用。 |
以下分别进行描述:
re.match函数:
import re
if __name__ == '__main__':
# re.match(pattern, string, flags=0)
line = "Cats are smarter than dogs"
pattern = r'(.*) are (.*?) (.*)'
matchObj = re.match(pattern, line, re.M|re.I)
if matchObj:
print("matchObj.group() : ", matchObj.group()) # matchObj.group(0)
print("matchObj.group(1) : ", matchObj.group(1))
print("matchObj.group(2) : ", matchObj.group(2))
print("matchObj.group(3) : ", matchObj.group(3))
print("matchObj.groups : ", matchObj.groups())
# 输出:
'''
matchObj.group() : Cats are smarter than dogs
matchObj.group(1) : Cats
matchObj.group(2) : smarter
matchObj.group(3) : than dogs
matchObj.groups : ('Cats', 'smarter', 'than dogs')
'''
re.search函数:
import re
if __name__ == '__main__':
# re.search(pattern, string, flags=0)
line = "Cats are smarter than dogs, dogs smarter than chicken"
pattern = '(smarter)'
matchObj = re.search(pattern, line, re.M|re.I)
if matchObj:
print("matchObj.group() : ", matchObj.group())
print("matchObj.group() : ", matchObj.group(1))
print("matchObj.groups : ", matchObj.groups())
# 输出,只能匹配一个,且扫描整个字符串
'''
matchObj.group() : smarter
matchObj.group() : smarter
matchObj.groups : ('smarter',)
'''
re.findall函数:
import re
if __name__ == '__main__':
# re.findall(pattern, string, flags=0)
line = "Cats are smarter than dogs, dogs smarter than chicken"
pattern = '(smarter)'
matchObj = re.findall(pattern, line, re.M|re.I)
if matchObj:
print("matchObj: ", matchObj)
# 输出, 找到正则表达式所匹配的所有子串,并返回一个列表
'''
matchObj: ['smarter', 'smarter']
'''
re.finditer函数:
和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。
import re
if __name__ == '__main__':
# re.finditer(pattern, string, flags=0)
line = "Cats are smarter than dogs, dogs smarter than chicken"
pattern = 'smarter'
matchObj = re.finditer(pattern, line, re.M|re.I)
# 可迭代对象
for it in matchObj:
print(it.group(), it.span())
# 输出
'''
smarter (9, 16)
smarter (33, 40)
'''
re.compile函数:
compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match, search, findall等方法使用 。
重写上述例子为:
pattern.match:
import re
if __name__ == '__main__':
# pattern.match(string)
line = "Cats are smarter than dogs"
pattern = r'(.*) are (.*?) (.*)'
# re.compile(pattern[, flags])
pa = re.compile(pattern, re.M|re.I)
matchObj = pa.match(line)
if matchObj:
print("matchObj.group() : ", matchObj.group()) # matchObj.group(0)
print("matchObj.group(1) : ", matchObj.group(1))
print("matchObj.group(2) : ", matchObj.group(2))
print("matchObj.group(3) : ", matchObj.group(3))
print("matchObj.groups : ", matchObj.groups())
pattern.search:
import re
if __name__ == '__main__':
# pattern.search(string)
line = "Cats are smarter than dogs, dogs smarter than chicken"
pattern = '(smarter)'
# re.compile(pattern[, flags])
pa = re.compile(pattern, re.M|re.I)
matchObj = pa.search(line)
if matchObj:
print("matchObj.group() : ", matchObj.group())
print("matchObj.group() : ", matchObj.group(1))
print("matchObj.groups : ", matchObj.groups())
pattern.findall:
import re
if __name__ == '__main__':
# pattern.findall(string)
line = "Cats are smarter than dogs, dogs smarter than chicken"
pattern = '(smarter)'
pa = re.compile(pattern, re.M|re.I)
matchObj = pa.findall(line)
if matchObj:
print("matchObj: ", matchObj)
pattern.finditer:
import re
if __name__ == '__main__':
# pattern.finditer(string)
line = "Cats are smarter than dogs, dogs smarter than chicken"
pattern = 'smarter'
pa = re.compile(pattern, re.M|re.I)
matchObj = pa.finditer(line)
# 可迭代对象
for it in matchObj:
print(it.group(), it.span())
参考:
1 正则表达式解析器