包含常用正则表达式的使用方法和技巧。
事实上,如果记不住如此多的用法,只需要牢牢掌握
.*
、.*?
、(.*)
和(.*?)
四个表达式,以及re.compile().findall()
方法即可。——by はるみ
Python
# 学习正则表达式的用法
import re
def output(obj, typeStr):
if obj:
# 匹配对象函数group(num)和groups(),用于获取匹配表达式
print(typeStr + "Obj.group() : ", obj.group())
print(typeStr + "Obj.group(1) : ", obj.group(1))
print(typeStr + "Obj.group(2) : ", obj.group(2))
print(typeStr + "Obj.groups() : ", obj.groups())
else:
print("No match!!")
def double(matched):
value = int(matched.group('value'))
return str(value * 2)
line = "Cats are smarter than dogs"
# 1. re.match
# 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话就返回None
# 语法:re.match(匹配的正则表达式, 要匹配的字符串, 标志位)
# re.match(pattern, string, flags=0)
# flags: 标志位,用于控制正则表达式的匹配方式
# 如: 是否区分大小写,多行匹配等
matchObj = re.match(r'(.*) are (.*?) dogs', line, re.M | re.I)
# 对上述正则表达式模式的解释
# r: 表示字符串为非转义的原始字符串,让编译器忽略转义字符(\),此处可有可无
# (.*): 式中第一个匹配分组,表示匹配除换行符之外的所有字符并计入匹配结果
# (.*?): 式中第二个匹配分组,带?表示懒惰模式,只匹配符合条件的最少字符并计入匹配结果
# .*: 没有括号包围,所以不是分组,匹配效果和(.*)相同,但不计入匹配结果
# 在上述模式作用下,原表达式的意思可以用中文翻译为:
# 匹配' are '(注意前后有空格)之前的所有字符和之后符合条件的最少字符并计入匹配结果,
# 再匹配后面剩余的所有字符但不计入匹配结果
# 最终使得 'Cats are smarter than dogs' 的匹配结果为('Cats', 'smarter')
output(matchObj, 'match')
# 2. re.search
# 扫描整个字符串并返回第一个成功的匹配
# re.search(pattern, string, flags=0)
searchObj = re.search(r'(.*) are (.*?) .*', line, re.M | re.I)
output(searchObj, 'search')
# 3. re.sub
# 用于替换字符串中的匹配项
# re.sub(pattern, repl, string, count=0, flags=0)
# repl: 替换的字符串,也可为一个函数
# count: 模式匹配后替换的最大次数,默认0表示替换所有的匹配
# 3.1 repl为字符串形式
phone = "2004-959-559 # 这是一个国外电话号码"
# 删除字符串中的Python注释
num1 = re.sub(r'#.*$', "", phone)
print("电话号码是:", num1)
# 删除非数字的字符
num2 = re.sub(r'\D', "", phone)
print("电话号码是:", num2)
# 3.2 repl为函数形式
# 将匹配的数字乘2
s = 'A23G4HFD567'
print(re.sub('(?P<value>\d+)', double, s))
# 4. re.compile
# 用于编译正则表达式,生成正则表达式对象(RegexObject),供re.match()和re.search()使用
# re.compile(pattern[, flags])
# 此处的pattern含义:用于匹配至少一个数字
pattern = re.compile(r'\d+')
# 从'o'开始匹配,匹配失败
m0 = pattern.match('one12twothree34four')
# 从'e'开始匹配,匹配失败
m1 = pattern.match('one12twothree34four', 2, 10)
# 从'1'开始匹配,匹配成功
m2 = pattern.match('one12twothree34four', 3, 10)
print(m2.group(0), m2.start(0), m2.end(0), m2.span(0))
# 5. re.findall
# 在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果有多个匹配模式,则返回元组列表
# 注:re.match()和re.search()仅匹配一次,re.findall()匹配所有
# re.findall(string[, pos[, endpos]])
# pos: 可选参数,指定字符串的起始位置,默认为0
# endpos: 可选参数,指定字符串的结束位置,默认为字符串的长度
# 5.1 单匹配模式
pattern1 = re.compile(r'\d+')
result1 = pattern1.findall('runoob 123 google 456')
result2 = pattern1.findall('run88oob123google456', 0, 10)
print(result1, result2)
# 5.2 多匹配模式
result3 = re.findall(r'(\w+)=(\d+)', 'set width=20 and height=10')
print(result3)
# 6. re.finditer
# 和re.findall()类似,在字符串中找到正则表达式所匹配的所有字串,并把它们作为一个迭代器返回
# re.finditer(pattern, string, flags=0)
it = re.finditer(r"\d+", "12a32bc43jf3")
for match in it:
print(match.group())
# 7. re.split
# 按照能够匹配的字串将字符串分割后返回列表
# re.split(pattern, string[, maxsplit=0, flags=0])
# maxsplit: 分割次数,默认值为0,不限制次数
print(re.split('\W+', ' runoob, runoob, runoob.'))
print(re.split('(\W+)', ' runoob, runoob, runoob.'))
print(re.split('\W+', ' runoob, runoob, runoob.', 1))