首先需要导入正则表达式模块
如:import re
r
标识后边字符不需要再转义了 如\\d
括号分组
num = re.compile(r'(\d\d\d)-(\d\d\d-\d\d\d\d)')
mo = num.search('My number is 415-555-4242.')
#获取第一组匹配结果 '415'
mo.group(1)
#获取第二组匹配结果 '555-4242'
mo.group(2)
#输出全匹配结果 '415-555-4242'
mo.group(0)
#输出全匹配结果 '415-555-4242'
mo.group()
#获取所有分组 ('415', '555-4242')
mo.groups()
mo.groups()
支持多重赋值 如:a,b = mo.groups()
用管道匹配多个分组
heroRegex = re.compile (r'Batman|Tina Fey')
mo1 = heroRegex.search('Batman and Tina Fey.')
# 输出匹配值 'Batman'
mo1.group()
mo2 = heroRegex.search('Tina Fey and Batman.')
# 输出匹配值 'Tina Fey'
mo2.group()
batRegex = re.compile(r'Bat(man|mobile|copter|bat)')
mo = batRegex.search('Batmobile lost a wheel')
# 输出结果 'Batmobile'
mo.group()
# 输出结果 'mobile' 匹配第一个分组括号内文本
mo.group(1)
用问号实现可选匹配
字符?
表明它前面的分组在这个模式中是可选的。出现的次数为0或1。
batRegex = re.compile(r'Bat(wo)?man')
mo1 = batRegex.search('The Adventures of Batman')
# 输出结果 'Batman'
mo1.group()
mo2 = batRegex.search('The Adventures of Batwoman')
# 输出结果 'Batwoman'
mo2.group()
phoneRegex = re.compile(r'(\d\d\d-)?\d\d\d-\d\d\d\d')
mo1 = phoneRegex.search('My number is 415-555-4242')
# 输出结果 '415-555-4242'
mo1.group()
mo2 = phoneRegex.search('My number is 555-4242')
# 输出结果 '555-4242'
mo2.group()
用星号匹配零次或多次
batRegex = re.compile(r'Bat(wo)*man')
mo1 = batRegex.search('The Adventures of Batman')
# 输出结果 'Batman'
mo1.group()
mo2 = batRegex.search('The Adventures of Batwoman')
# 输出结果 'Batwoman'
mo2.group()
mo3 = batRegex.search('The Adventures of Batwowowowoman')
# 输出结果 'Batwowowowoman'
mo3.group()
用加号匹配一次或多次
*
匹配零次或多次 +
匹配一次或多次 必须出现一次
batRegex = re.compile(r'Bat(wo)+man')
mo1 = batRegex.search('The Adventures of Batman')
# 输出结果 True
mo1 == None
mo2 = batRegex.search('The Adventures of Batwoman')
# 输出结果 'Batwoman'
mo2.group()
mo3 = batRegex.search('The Adventures of Batwowowowoman')
# 输出结果 'Batwowowowoman'
mo3.group()
用花括号匹配特定次数
{3}
必须匹配3次 {3,}
匹配3次或3次以上 {,3}
匹配0到3次
haRegex = re.compile(r'(Ha){3}')
mo1 = haRegex.search('HaHaHa')
# 输出结果 'HaHaHa'
mo1.group()
贪心和非贪心匹配
greedyHaRegex = re.compile(r'(Ha){3,5}')
mo1 = greedyHaRegex.search('HaHaHaHaHa')
# 输出结果 'HaHaHaHaHa' 贪心匹配
mo1.group()
nongreedyHaRegex = re.compile(r'(Ha){3,5}?')
mo2 = nongreedyHaRegex.search('HaHaHaHaHa')
# 输出结果 'HaHaHa' 非贪心匹配
mo2.group()
findall()方法
phoneNumRegex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d')
mo = phoneNumRegex.search('Cell: 415-555-9999 Work: 212-555-0000')
# 输出结果 '415-555-9999'
mo.group()
phoneNumRegex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d')
# 输出结果 ['415-555-9999', '212-555-0000'] 不包含分组
phoneNumRegex.findall('Cell: 415-555-9999 Work: 212-555-0000')
phoneNumRegex = re.compile(r'(\d\d\d)-(\d\d\d)-(\d\d\d\d)')
# 输出结果 [('415', '555', '1122'), ('212', '555', '0000')] 包含分组
phoneNumRegex.findall('Cell: 415-555-9999 Work: 212-555-0000')
建立自己的字符分类
# [aeiouAEIOU] 自己定义内容
vowelRegex = re.compile(r'[aeiouAEIOU]')
# 输出结果 ['o', 'o', 'o', 'e', 'a', 'a', 'o', 'o', 'A', 'O', 'O']
vowelRegex.findall('RoboCop eats baby food. BABY FOOD.')
# 不包含 [aeiouAEIOU]
consonantRegex = re.compile(r'[^aeiouAEIOU]')
# 输出结果 ['R', 'b', 'c', 'p', ' ', 't', 's', ' ', 'b', 'b', 'y', ' ', 'f', 'd', '.', ' ', 'B', 'B', 'Y', ' ', 'F', 'D', '.']
consonantRegex.findall('RoboCop eats baby food. BABY FOOD.')
插入字符和美元字符
^
以什么开始 $
以什么开始
beginsWithHello = re.compile(r'^Hello')
# 输出结果 <_sre.SRE_Match object; span=(0, 5), match='Hello'>
beginsWithHello.search('Hello world!')
# 输出结果 True
beginsWithHello.search('He said hello.') == None
endsWithNumber = re.compile(r'\d$')
# 输出结果 <_sre.SRE_Match object; span=(16, 17), match='2'>
endsWithNumber.search('Your number is 42')
# 输出结果 True
endsWithNumber.search('Your number is forty two.') == None
wholeStringIsNum = re.compile(r'^\d+$')
wholeStringIsNum.search('1234567890')
# 输出结果 <_sre.SRE_Match object; span=(0, 10), match='1234567890'>
# 输出结果 True
wholeStringIsNum.search('12345xyz67890') == None
# 输出结果 True
wholeStringIsNum.search('12 34567890') == None
通配字符
句点字符只匹配一个字符,要匹配真正的句点,就是用倒斜杠转义:\.
atRegex = re.compile(r'.at')
# 输出结果 ['cat', 'hat', 'sat', 'lat', 'mat']
atRegex.findall('The cat in the hat sat on the flat mat.')
# 不包含 [aeiouAEIOU]
consonantRegex = re.compile(r'[^aeiouAEIOU]')
# 输出结果 ['R', 'b', 'c', 'p', ' ', 't', 's', ' ', 'b', 'b', 'y', ' ', 'f', 'd', '.', ' ', 'B', 'B', 'Y', ' ', 'F', 'D', '.']
consonantRegex.findall('RoboCop eats baby food. BABY FOOD.')
用点-星匹配所有字符
nameRegex = re.compile(r'First Name: (.*) Last Name: (.*)')
mo = nameRegex.search('First Name: Al Last Name: Sweigart')
# 输出结果 'Al'
mo.group(1)
# 输出结果 'Sweigart'
mo.group(2)
点-星使用“贪心”模式:它总是匹配尽可能多的文本。要用“非贪心”模式匹配 所有文本,就使用点-星和问号。像和大括号一起使用时那样,问号告诉 Python 用非贪 心模式匹配。
nongreedyRegex = re.compile(r'<.*?>')
mo = nongreedyRegex.search('<To serve man> for dinner.>')
# 输出结果 '<To serve man>'
mo.group()
greedyRegex = re.compile(r'<.*>')
mo = greedyRegex.search('<To serve man> for dinner.>')
# 输出结果 '<To serve man> for dinner.>'
mo.group()
用句点字符匹配换行
re.DOTALL
可以匹配换行数据
noNewlineRegex = re.compile('.*')
# 输出结果 'Serve the public trust.'
noNewlineRegex.search('Serve the public trust.\nProtect the innocent. \nUphold the law.').group()
newlineRegex = re.compile('.*', re.DOTALL)
# 输出结果 'Serve the public trust.\nProtect the innocent.\nUphold the law.'
newlineRegex.search('Serve the public trust.\nProtect the innocent.
\nUphold the law.').group()
用 sub()方法替换字符串
namesRegex = re.compile(r'Agent \w+')
# 输出结果 'CENSORED gave the secret documents to CENSORED.'
namesRegex.sub('CENSORED', 'Agent Alice gave the secret documents to Agent Bob.')
\1
代表第一个分组
agentNamesRegex = re.compile(r'Agent (\w)\w*')
# 输出结果 A**** told C**** that E**** knew B**** was a double agent.
agentNamesRegex.sub(r'\1****', 'Agent Alice told Agent Carol that Agent Eve knew Agent Bob was a double agent.')
管理复杂的正则表达式
re.VERBOSE
可以让复杂的正则表达式支持注释,多个的话用 |
隔开 比如:re.IGNORECASE | re.DOTALL | re.VERBOSE
phoneRegex = re.compile(r'''((\d{3}|\(\d{3}\))? #注释1
(\s|-|\.)?\d{3}(\s|-|\.) #注释2
\d{4} #注释3
(\s*(ext|x|ext.)\s*\d{2,5})?)''', re.VERBOSE)
字符分类
缩写字符分类 | 表示 |
---|---|
\d | 0 到 9 的任何数字 |
\D | 除 0 到 9 的数字以外的任何字符 |
\w | 任何字母、数字或下划线字符(可以认为是匹配“单词”字符) |
\W | 除字母、数字和下划线以外的任何字符 |
\s | 空格、制表符或换行符(可以认为是匹配“空白”字符) |
\S | 除空格、制表符和换行符以外的任何字符 |
- ?匹配零次或一次前面的分组。
- *匹配零次或多次前面的分组。
- +匹配一次或多次前面的分组。
- {n}匹配 n 次前面的分组。
- {n,}匹配 n 次或更多前面的分组。
- {,m}匹配零次到 m 次前面的分组。
- {n,m}匹配至少 n 次、至多 m 次前面的分组。
- {n,m}?或*?或+?对前面的分组进行非贪心匹配。
- ^spam 意味着字符串必须以 spam 开始。
- spam$意味着字符串必须以 spam 结束。
- .匹配所有字符,换行符除外。
- \d、\w 和\s 分别匹配数字、单词和空格。
- \D、\W 和\S 分别匹配出数字、单词和空格外的所有字符。
- [abc]匹配方括号内的任意字符(诸如 a、b 或 c)。
- [^abc]匹配不在方括号内的任意字符。
参考内容:
- 《Automate the Boring Stuff with Python》
- https://docs.python.org/zh-cn/3/library/re.html