python正则表达式
python 中的正则表达式
正则表达式用来匹配字符串中特定的字符
正则表达式简称 regex
例如\d 是一个正则表达式,表示以为数字字符,即任何一位 0-9 的数字.
python 中的所有表达式的函数都在 re 模块中例如
1 | import re |
匹配 regex 对象
regex 对象的 search 方法传入要查找的字符串,寻找该正则表达式的所有匹配,如果
没有找到则返回 none,如果找到了该模式,search 方法返回一个 match 对象,match 对象,有一个 group 方法,他返回被查找字符串中实际匹配的文本
mo = phonNumRegex.search(‘my number is 455-333-1234’)
print(f’phone number is: {mo.group()}')
在 python 中使用正则表达式有几个步骤:
使用 import re 导入模块
使用 re.complile 函数方法创建一个 regex 对象
想 regex 对象的 search 方法传入想要查找的字符串,他返回一个 match 对象
调用 match 对象的 group 方法,返回实际匹配文本的字符串
用正则表达式匹配更多模式
利用括号分组
假定想要将区号从电话号码中分离,添加括号将在正则表达式中分组:(\d\d\d)-(\d\d\d-\d\d\d),然后使用 group 匹配对象方法,冲分组中获取匹配的文本
1 |
|
如果一次性要获得所有分组需要调用 groups()
1 |
|
利用管道匹配多个分组字符|称为管道,希望匹配许多表达式中的一个时,就可以使它,例如 r’Batman|Tina Fey’ 将匹配’Batman’ 或 ‘Tina Fey’
1 | heroRegex = re.compile(r'Batman|Tian Fay') |
利用 findall 方法可以找到所有匹配的方法,后面会讲 print(‘_’ _ 32)使用问好实现可选匹配有时候匹配的模式是可选的,也就是说无论这段文本在不在,正则表达式都会认为匹配字符?标识他前面的分组在这个模式中是可选的,例如
1 | batRegex = re.compile(r'Bat(wo)?man') |
使用星号进行 0 次或者多次的匹配
意味着要进行 0 次或者多次的匹配,即在之前进行分组,可以在文本中出现任意次数
也可以完全不存在,或一次又一次的重复例如:
1 |
|
使用加号匹配一次或者多次
- 意味着匹配 0 次或者多次,+则意味着匹配一次或者多次,星号不要求分组出现在匹配
的字符串中,但是加号不同,加号前面的分组必须’至少出现一次’
1 | batRegex = re.compile(r'Bat(wo)+man') |
使用花括号匹配特定次数
如果想要一个分组特定次数,就在正则表达式中改分组的后面,跟上花括号包裹的数字
例如正则表达式的(Ha){3}将匹配字符串’HaHaHa’,但不会匹配’HaHa’因为后者字符串只出现了两次除了一个数字,还可以指定一个范围,即在花括号中写下一个最小值,一个逗号一个最大值例如(Ha){1,3} 将匹配’HaHaHa’ ‘HaHa’ ‘Ha’,也可以不写花括号中的第一个或者第二个数字,不限定最小值和最大值例如(ha){3,}将匹配三次和更多次数,(ha){,5}将匹配 0 到 5 次
1 | haRegex = re.compile(r'(ha){3}') |
贪心匹配和非贪心匹配
在字符串’hahaha’中因为(ha){1,3}可以匹配 1,2,3 个实例,那么为什么字符串
'hahaha’的 Match 对象调用 group()方法会返回’hahaha’而不是’ha’之类的比较短的结果因为 python 的正则表达式默认是匹配更多的即’贪心’的,这表示在二意的情况去,它会尽可能的匹配最长的字符串,而花括号的非贪心版本匹配尽可能短的字符串,即在结束的花括号后跟着一个问好
1 | greedyHaRegex = re.compile(r'(ha){3,5}?') |
findall()方法
除了 search 方法之外 Regex 对象还有一个 findall 方法,search 方法将返回一个 Match 对象包含被查找字符串中第一次匹配的的文本,而 findall 方法将返回一组字符串,包含被查找字符串中的所有匹配
1 | phonNumRegex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d') |
findall 方法返回一个列表
1 | print(phonNumRegex.findall('call: 515-222-1234 work: 121-333-1231')) |
- 字符分类
- \d 0-9 的任何数字
- \D 除了 0-9 之外的任意字符
- \w 任何字母,数字或下划线(可以认为是匹配’单词’字符)
- \W 除了字母,数字和下划线以外的任何字符
- \s 空格,制表符或换行符(可以认为匹配’空白’字符)
- \S 除了空格制表符或者换行符以外的任何字符
字符分类对于缩短正则表达式很有用,字符分类[0-5]只匹配数字 0-5
插入字符
可以在正则表达式的开始处使用插入符号^,标明匹配必须发生在被查找文本的开始处类似的,可以在正则表达式的末尾加上$,表示该字符串必须以这个正则表达式的模式结束可以同时使用^和$
例如使用 r’Hello’匹配以’Hello’开始的字符串
1 | beginsWithHello = re.compile(r'^hello') |
beginsWithHello.search(‘he said hello’) 这条是无法匹配的
正则表达式 r’\d$'匹配以数字 0-9 结束的字符串
1 |
|
正则表达 r’\d+$'表示匹配数字开头和结尾的字符串
1 | wholeStringIsNum = re.compile(r'\d+$') |
通配字符
在正则表达式中 . 字符被称为"通配符",它匹配除了换行之外的所有字符
1 | atRegex = re.compile(f'.at') |
.at 只匹配一个字符这也就是上面的 flat 只匹配到 flat
用.* 匹配所有字符
1 | nameRegex = re.compile(f'First Name:(.*) Last Name:(.*)') |
用句点字符匹配换行
.*将匹配除了换行之外的所有字符,通过传入 re.DOTALL 作为 re.compole 的第二个参数
可以让.匹配所有字符,包括换行符
1 |
|
正则表达式符号复现
- ?匹配零次或者一次前面的分组
- *匹配零次或者多次前面的分组
- +匹配一次或者多次前面的分组
- {n}匹配 n 次前面的分组
- {n,}匹配 n 次到多次前面的分组
- {,m} 匹配零次到 m 次前面的分组
- {n,m}匹配至少 n 次,至多 m 次前面的分组
- {n,m}?或*?或+?对前面的分组都是进行非贪心算法
- ^spam 意味着字符串必须与 spam 开始
- spam$ 意味着字符串必须与 spam 结尾
- .匹配所有字符,除了换行符
- \d,\w,\s 分别匹配数字单词和空格
- \D,\W,\S 分别匹配出数字,单词和空格外的所有字符
- [abc]匹配方括号内的任意字符
- [^abc]匹配不在方括号内的任意字符
不区分大小写
不区分大小写可以向 compile 传入第二个参数 re.I 或者 re.IGNORECASE
1 | pobocop = re.compile(r'robocop', re.I) |
使用 sub 方法替换字符串
正则表达式不仅能够找到文本模式,而且能够用新的文本替换掉这些模式,Regex 对象的 sub 方法需要传入两个参数,第一个是字符串,用于取代发现的匹配,第二个参数是一个字符串,用于正则表达式匹配的内容,返回替换完成的字符串
1 | nameRegex = re.compile(r'Agent \w+') |