Contents
11.8. 用正则表达式匹配更多模式¶
11.8.1. 利用括号分组¶
#!/usr/bin/env python
# -*- coding:utf8 -*-
# auther; 18793
# Date:2020/3/22 15:23
# filename: main.py
import re
phoneNum = re.compile(r"(\d\d\d)-(\d\d\d-\d\d\d\d)")
mo = phoneNum.search("My number is 415-555-4242.")
print(mo.group(1)) # 415
print(mo.group(2)) # 555-4242
print(mo.group(0)) # 415-555-4242
print(mo.group()) # 415-555-4242
11.8.2. 用管道匹配多个分组¶
#!/usr/bin/env python
# -*- coding:utf8 -*-
# auther; 18793
# Date:2020/3/22 15:26
# filename: re-main2.py
import re
herRegex = re.compile(r'Batman|Tina Fey')
mo1 = herRegex.search("Batman and Tina Fey")
print(mo1.group()) # Batman
mo2 = herRegex.search("Tina Fey and Batman ")
print(mo2.group()) # Tina Fey
batRegex = re.compile(r"Bat(man|mobile|copter|bat)")
mo = batRegex.search("Batmobile lost a wheel")
print(mo.group()) # Batmobile
print(mo.group(1)) # mobile
11.8.3. 用问号实现可选匹配¶
#!/usr/bin/env python
#-*- coding:utf8 -*-
# auther; 18793
# Date:2020/3/22 15:33
# filename: re-main3.py
import re
batRegex = re.compile(r"Bat(wo)?man")
mo1 = batRegex.search("The Adventures of Batman")
print(mo1.group()) #Batman
mo2 = batRegex.search("The Adventures of Batwoman")
print(mo2.group()) #Batwoman
11.8.4. 用星号匹配零次或多次¶
#!/usr/bin/env python
# -*- coding:utf8 -*-
# auther; 18793
# Date:2020/3/22 15:37
# filename: re-main4.py
import re
batRegex = re.compile(r'Bat(wo)*man')
mo1 = batRegex.search('The Adventures of Batman')
print(mo1.group()) # Batman
mo2 = batRegex.search('The Adventures of Batwoman')
print(mo2.group()) # Batwoman
mo3 = batRegex.search('The Adventures of Batwowowowoman')
print(mo3.group()) # Batwowowowoman
11.8.5. 用加号匹配一次或多次¶
#!/usr/bin/env python
# -*- coding:utf8 -*-
# auther; 18793
# Date:2020/3/22 15:37
# filename: re-main4.py
import re
batRegex = re.compile(r'Bat(wo)+man')
mo1 = batRegex.search('The Adventures of Batwoman')
print(mo1.group()) # Batman
mo2 = batRegex.search('The Adventures of Batwowowowowowoman')
print(mo2.group()) # Batwowowowowowoman
mo3 = batRegex.search('The Adventures of Batman')
print(mo3 == None) # True
11.8.6. 用花括号匹配特定次数¶
#!/usr/bin/env python
# -*- coding:utf8 -*-
# auther; 18793
# Date:2020/3/22 15:41
# filename: re-main5.py
import re
haregex = re.compile(r"(Ha){3}")
mo1 = haregex.search("HaHaHa")
print(mo1.group()) # HaHaHa
mo2 = haregex.search("Ha")
print(mo2 == None) # True
11.8.7. 贪心和非贪心匹配¶
#!/usr/bin/env python
# -*- coding:utf8 -*-
# auther; 18793
# Date:2020/3/22 15:48
# filename: re-main6.py
import re
# 贪婪匹配
regreedyHaRegex = re.compile(r"(Ha){3,5}")
mo1 = regreedyHaRegex.search("HaHaHaHaHa")
print(mo1.group()) # HaHaHaHaHa
# 非贪婪匹配
regreedyHaRegex = re.compile(r"(Ha){3,5}?")
mo1 = regreedyHaRegex.search("HaHaHaHaHa")
print(mo1.group()) # HaHaHa
11.8.8. 通配字符¶
.匹配单个字符¶
.(句点)字符称为“通配符”。它匹配除了换行之外的所有字符,句点字符只匹配一个字符。
atRegex = re.compile(r'.at')
result = atRegex.findall('The cat in the hat sat on the flat mat.')
print(result) #['cat', 'hat', 'sat', 'lat', 'mat']
用点-星匹配所有字符¶
(.*) #贪婪匹配模式
(.*?) #非贪婪匹配模式
点-星使用“贪心”模式:它总是匹配尽可能多的文本。要用“非贪心”模式匹配所有文本,就使用点-星和问号。 像和大括号一起使用时那样,问号告诉Python 用非贪心模式匹配。
#!/usr/bin/env python
#-*- coding:utf8 -*-
# auther; 18793
# Date:2020/3/22 15:57
# filename: sample01.py
import re
nameRegex = re.compile(r'First Name: (.*) Last Name: (.*)')
mo = nameRegex.search('First Name: Al Last Name: Sweigart')
print(mo.group(1)) #Al
print(mo.group(2)) #Sweigart
nongreedyRegex = re.compile(r'<.*?>')
mo = nongreedyRegex.search('<To serve man> for dinner.>')
print(mo.group()) #<To serve man>
用句点字符匹配换行¶
#!/usr/bin/env python
# -*- coding:utf8 -*-
# auther; 18793
# Date:2020/3/22 16:00
# filename: sample02.py
import re
noNewlineRegex = re.compile('.*')
result = noNewlineRegex.search('Serve the public trust.\nProtect the innocent.\nUphold the law.').group()
print(result)
# 通过传入 re.DOTALL 作为 re.compile()的第二个参数,可以让句点字符匹配所有字符,包括换行字符
newlineRegex = re.compile('.*', re.DOTALL)
result = newlineRegex.search('Serve the public trust.\nProtect the innocent.\nUphold the law.').group()
print(result)
11.8.9. 正则表达式符号简述¶
?匹配零次或一次前面的分组。
*匹配零次或多次前面的分组。
+匹配一次或多次前面的分组。
{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]匹配不在方括号内的任意字符。
11.8.10. 不区分大小写的匹配¶
#!/usr/bin/env python
# -*- coding:utf8 -*-
import re
robocop = re.compile(r'robocop', re.I)
result1 = robocop.search('RoboCop is part man, part machine, all cop.').group()
print(result1)
result2 = robocop.search('ROBOCOP protects the innocent.').group()
print(result2)
result3 = robocop.search('Al, why does your programming book talk about robocop so much?').group()
print(result3)
11.8.11. 管理复杂的正则表达式¶
要实现这种详细模式,可以向re.compile()传入变量re.VERBOSE,作为第二个参数。
可以将正则表达式放在多行中,并加上注释
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)
使用了三重引号('''),创建了一个多行字符串。这样就可以将正则表达式定义放在多行中,让它更可读。
正则表达式字符串中的注释规则,与普通的 Python 代码一样:#符号和它后面直到行末的内容,都被忽略。 而且,表示正则表达式的多行字符串中,多余的空白字符也不认为是要匹配的文本模式的一部分。这让你能够组织正则表达式,让它更可读。
11.8.12. 组合使用 re.IGNOREC ASE、re.DOTALL 和 re.VERBOSE¶
如果希望正则表达式不区分大小写,并且句点字符匹配换行
someRegexValue = re.compile('foo', re.IGNORECASE | re.DOTALL)
或者
someRegexValue = re.compile('foo', re.IGNORECASE | re.DOTALL | re.VERBOSE)