对正则知识的整理,方便自己以后复习。这一部分内容,自己必须耐下心来好好整理一下。对于正则表达式每个符号的含义都需要进行记忆。
例子 1:匹配文本中特定模式的电话号
import re# compile()返回一个 Regex 模式对象phoneNumRegex = re.compile(r'\d{3}-\d{3}-\d{4}')# search()方法将返回一个 Match 对象mo = phoneNumRegex.search('My number is 415-555-4242.')# group()会返回匹配的结果print('Phone number found: ' + mo.group())
正则表达式匹配过程可视化网站:https://www.regexpal.com/
(分组)例子 2: 将区号从电话号码中分离
import rephoneNumRegex = re.compile(r'(\d{3})-(\d{3}-\d{4})')mo = phoneNumRegex.search('My number is 415-555-4242.')# 向 group() 方法传入 0 或不传入参数,将返回整个匹配的文本print('mo.group(): ' + mo.group())print('mo.group(0): ' + mo.group(0))# 向 group() 匹配对象方法传入整数 1 或 2,就可以取得匹配文本的不同部分print('mo.group(1): ' + mo.group(1))print('mo.group(2): ' + mo.group(2))# mo.group(): 415-555-4242# mo.group(0): 415-555-4242# mo.group(1): 415# mo.group(2): 555-4242
(管道)用管道匹配多个分组
- 字符
|称为“管道”。希望匹配许多表达式中的一个时,就可以使用它 - 如果 Batman 和 Tina Fey 都出现在被查找的字符串中,第一次出现的匹配文本, 将作为 Match 对象返回 ```python import re
heroRegex = re.compile(r’Batman|Tina Fey’)
mo1 = heroRegex.search(‘Batman and Tina Fey.’) print(mo1.group()) # Batman
mo2 = heroRegex.search(‘Tina Fey and Batman.’) print(mo2.group()) # Tina Fey
```pythonimport rebatRegex = re.compile(r'Bat(man|mobile|copter|bat)')mo = batRegex.search('Batmobile lost a wheel')print(mo.group()) # Batmobile# 返回第一个括号分组内匹配的文本print(mo.group(1)) # mobile
import re# 字符?表明它前面的分组在这个模式中是可选的# 不论这段文本在不在,正则表达式都会认为匹配batRegex = re.compile(r'Bat(wo)?man')mo1 = batRegex.search('The Adventures of Batman') # Batmanprint(mo1.group())mo2 = batRegex.search('The Adventures of Batwoman') # Batwomanprint(mo2.group())
import re# 字符*匹配零次或多次batRegex = re.compile(r'Bat(wo)*man')mo1 = batRegex.search('The Adventures of Batman')print(mo1.group())mo2 = batRegex.search('The Adventures of Batwoman') # Batwomanprint(mo2.group())mo3 = batRegex.search('The Adventures of Batwowowowoman')print(mo3.group())
import re# 字符+匹配一次或多次batRegex = re.compile(r'Bat(wo)+man')mo1 = batRegex.search('The Adventures of Batman')if mo1 is None:print(None)mo2 = batRegex.search('The Adventures of Batwoman') # Batwomanprint(mo2.group())mo3 = batRegex.search('The Adventures of Batwowowowoman')print(mo3.group())
# 用花括号匹配特定次数# 如果想要一个分组重复特定次数,就在正则表达式中该分组的后面import rehaRegex = re.compile(r'(Ha){3}')mo1 = haRegex.search('HaHaHa')print(mo1.group())mo2 = haRegex.search('Ha')print(mo2 is None)
Python 的正则表达式默认是“贪心”的,即会尽可能匹配最长的字符串。
修改为非贪心( 在结束的花括号后跟一个问号 ):
import regreedyHaRegex = re.compile(r'(Ha){3,5}')mo1 = greedyHaRegex.search('HaHaHaHaHa')print(mo1.group())nongreedyHaRegex = re.compile(r'(Ha){3,5}?')mo2 = nongreedyHaRegex.search('HaHaHaHaHa')print(mo2.group())
search() 和 findall() 的区别:
- search() 将返回一个Match 对象,包含被查找字符串中的“第一次”匹配的文本
- findall() 方法将返回一个 list,包含被查找字符串中的所有匹配
- 如果调用在一个没有分组的正则表达式上, findall() 将返回一个匹配字符串的列表
- 如果调用在一个有分组的正则表达式上,方 法 findall() 将返回一个字符串的元组的列表(每个分组对应一个字符串)
```python import re
phoneNumRegex = re.compile(r’\d\d\d-\d\d\d-\d\d\d\d’) # has no groups print(phoneNumRegex.findall(‘Cell: 415-555-9999 Work: 212-555-0000’))
[‘415-555-9999’, ‘212-555-0000’]
```pythonimport rephoneNumRegex = re.compile(r'(\d\d\d)-(\d\d\d)-(\d\d\d\d)') # has groupsprint(phoneNumRegex.findall('Cell: 415-555-9999 Work: 212-555-0000'))# [('415', '555', '9999'), ('212', '555', '0000')]
插入字符和美元字符
可以用 ^ 和 $ 字符来卡范围。例如, r'^Hello' 表示匹配以 Hello 开头的内容, r'\d$' 匹配以数字结束的内容, r'^\d+$' 匹配从开始到结束都是数字的字符串。
用句点字符匹配换行
通过传入 re.DOTALL 作为 re.compile()的第 二个参数,可以让句点字符匹配所有字符,包括换行字符
import renoNewlineRegex = re.compile('.*')print(noNewlineRegex.search('Serve the public trust.\nProtect the innocent.\nUphold the law.').group())newlineRegex = re.compile('.*', re.DOTALL)print(newlineRegex.search('Serve the public trust.\nProtect the innocent.\nUphold the law.').group())
不区分大小写的匹配
- 要让正则表达式 不区分大小写,可以向
re.compile()传入re.IGNORECASE或re.I,作为第二个参数。
用 sub()方法替换字符串
管理复杂的正则表达式
有时候正则表达式会很长很复杂,这时候要对正则表达式的每个部分进行说明,则可以用下面的方法:
你可以告诉 re.compile(),忽略正则表达式字符 串中的空白符和注释,从而缓解这一点。要实现这种详细模式,可以向 re.compile() 传入变量 re.VERBOSE,作为第二个参数。
例如:
phoneRegex = re.compile(r'((\d{3}|\(\d{3}\))?(\s|-|\.)?\d{3}(\s|-|\.)\d{4}(\s*(ext|x|ext.)\s*\d{2,5})?)')
可改为:
phoneRegex = re.compile(r'''((\d{3}|\(\d{3}\))? # area code(\s|-|\.)? # separator\d{3} # first 3 digits(\s|-|\.) # separator\d{4} # last 4 digits(\s*(ext|x|ext.)\s*\d{2,5})? # extension)''', re.VERBOSE)
组合使用 re.IGNOREC ASE、re.DOTALL 和 re.VERBOSE
re.compile()函数只接受一 个值作为它的第二参数。可以使用管道字符(|)将变量组合起来,从而绕过这个限 制。管道字符在这里称为“按位或”操作符。
someRegexValue = re.compile('foo', re.IGNORECASE | re.DOTALL | re.VERBOSE)

