使用正则表达式查找文本模式
导入re模块
import re
向 re.compile() 传入字符串值,比如创建一个对象来匹配11位的手机号码
phoneNumber1 = re.compile(r'\d\d\d-\d\d\d\d-\d\d\d\d')
在字符串的第一个引号前加上 r 表示该字符串为原始字符串,不需要转义字符/
寻找匹配
mo1 = phoneNumber1.search('My number is 111-1111-1111.')
print('Phone number is : '+mo1.group())
输出结果
用正则表达式匹配更多模式
利用括号分组
加入括号进行分组
phoneNumber1 = re.compile(r'(\d\d\d)-(\d\d\d\d-\d\d\d\d)')
寻找匹配
phoneNumber2 = re.compile(r'(\d\d\d)-(\d\d\d\d-\d\d\d\d)')
mo2 = phoneNumber2.search('My number is 111-1111-1111')
number1, number2 = mo2.groups()
print(number1+' '+number2)
print(mo2.group(1))
print(mo2.group(2))
输出结果
用管道匹配多个分组
字符|被称为管道,可以使用它匹配多个表达式
代码
name = re.compile(r'Mike|Rose')
name1 = name.search('Mike and Rose')
name2 = name.search('Rose and Mike')
name3 = name.findall('Mike and Rose')
print(name1.group()+' '+name2.group()+'\n'+str(name3))
输出结果
用问号实现可选匹配
字符?表示它前面的分组在这个匹配模式中是可选的,匹配零次或一次
代码
batRegex = re.compile(r'Bat(wo)?man')
mo1 = batRegex.search('Batman')
mo2 = batRegex.search('Batwoman')
print(mo1.group()+' '+mo2.group())
输出结果
四星号,加号,花括号
*意味着匹配零次或多次,+意味着匹配一次或多次,{x,y}意味着匹配x到y次数
代码
batRegex1 = re.compile(r'Bat(wo)*man')
mo1 = batRegex1.search('Batman')
mo2 = batRegex1.search('Batwoman')
print(mo1.group()+' '+mo2.group())
batRegex2 = re.compile(r'Bat(wo)+man')
mo3 = batRegex2.search('Batwoman')
mo4 = batRegex2.search('Batwowoman')
mo5 = batRegex2.search('Batwowowowoman')
print(mo3.group()+' '+mo4.group()+' '+mo5.group())
batRegex3 = re.compile(r'(wo){1,3}')
mo6 = batRegex3.search('wowowo')
mo7 = batRegex3.search('wowo')
print(mo6.group()+' '+mo7.group())
输出结果
贪心和非贪心匹配
python的正则表达式默认是贪心的,说明在有二义的情况下,他们会尽可能匹配长的字符串。花括号后面加上一个?表示花括号的非贪心模式
代码:
batRegex3 = re.compile(r'(wo){1,3}?') //比上面多了一个'?'
mo6 = batRegex3.search('wowowo')
mo7 = batRegex3.search('wowo')
print(mo6.group()+' '+mo7.group())
输出结果:
字符分类
常用字符分类
缩写字符分类 | 表示 |
---|---|
d | 0到9的任何数字 |
D | 除0到9的数字以外的任何字符 |
w | 任何字母,数字或下划线字符 |
W | 除字母,数字或下划线以外的任何字符 |
s | 空格,制表符或换行符 |
S | 除空格,制表符或换行符以外的任何字符 |
示例:
nu_alRegex = re.compile(r'\d+\s\w+')
all1 = nu_alRegex.findall('1 a,2 b,33 cc,44 ddd')
print(str(all1))
运行结果:
建立自己的字符分类
有时候自带的字符分类太过于广泛了,所以我们就要建立自己的字符分类
示例:
mywordRegex = re.compile(r'[a-eABCDE?!]')
mywords = mywordRegex.findall('I have a pen ? I have an Apple !')
print(str(mywords))
运行结果:
在[]内一些正则表达式符号不会被解释,所以不用加 ' ' 进行转义
也可以在[]内加上一个^符号,表示不包括这些字符
例如:
mywordRegex = re.compile(r'[^a-eABCDE?!]')
^和$字符
在正则表达式的开始使用 ^ ,表示匹配以^后面的字符串开始的字符串,而$表示匹配以$前面的字符串为结束的字符串。
示例:
beginWithRegex = re.compile(r'^hello')
begin = beginWithRegex.search('hello world')
endWidthRegex = re.compile(r'world$')
end = endWidthRegex.search('hello world')
print(begin.group()+"\n"+end.group())
运行结果:
通配字符
正则表达式中, . 称为通配符,它表示除了换行之外的所有字符。
示例:
dotRegex = re.compile(r'.at')
dot = dotRegex.findall('The cat in the hat sat on the flat mat.')
print(str(dot))
运行结果:
注意:'.' 只匹配at前面的一个字符
用 .* 匹配所有字符
示例:
hwRegex = re.compile(r'begin:(.*) end:(.*)')
hw = hwRegex.search('begin: hello end: world')
print(hw.group(1)+' '+hw.group(2))
运行结果:
.*使用贪心模式,它会匹配尽可能多的字符,可以在后面加一个 ? 让其使用非贪心模式(类比{}的使用)