目录
所谓正则表达式(regex),就是一种模式匹配,学会用正则匹配,就可以达到事半功倍的效果。
一、正则表达式在python中如何使用
1.导入正则表达式模块
# 导入re模块
import re
2.创建正则表达式对象,以电话号码为例
# 使用re.compile()方法创建一个Regex对象,模式为'\d\d\d-\d\d\d-\d\d\d\d'
test_regex=re.compile(r'\d\d\d-\d\d\d-\d\d\d\d')
Tips:在字符串的第一个引号前面加个r,代表将该字符串标识为原始字符串,不包含转义字符
3.匹配正则表达式
使用Regex的search()对象查找传入的字符串,寻找该正则表达式的所有匹配。
# 使用search()方法传入要匹配的字符串,并返回一个match对象
mo=test_regex.search('My number is 415-425-2222.')
4.输出匹配文本的字符串
如果没有找到该正则表达式模式,serch()将返回None。
如果找到了该模式,则返回一个Match对象。Match对象有一个group()方法,返回被查找字符串中实际匹配的文本。
# 输出匹配的字符串
print(mo.group())
运行结果如下:
二、用正则表达式匹配更多模式
1.利用括号分组,比如分为两组,区号和号码
①group()方法传入1代表第一组,2代表第二组,0或不传代表全部
test_regex=re.compile(r'(\d\d\d)-(\d\d\d-\d\d\d\d)')
mo=test_regex.search('My number is 415-425-2222')
# 返回区号
print(mo.group(1))
# 返回全部匹配
print(mo.group())
运行结果如下:
②如果想一次获取所有分组,需要使用groups(),该方法将以元组的形式返回所有分组
test_regex=re.compile(r'(\d\d\d)-(\d\d\d-\d\d\d\d)')
mo=test_regex.search('My number is 415-425-2222')
#返回所有分组
print(mo.groups())
运行结果如下:
2.用管道符(|)匹配多个分组
如果想同时匹配hello,python,就可以使用hello|python。search()方法是返回第一个匹配的字符,findall()则返回所有的匹配,返回对象类型为字符串列表。
test_regex=re.compile('hello|python')
mo1=test_regex.search('hello,python')
print(mo1.group())
mo2=test_regex.search('python,hello')
print(mo2.group())
mo3=test_regex.findall('python,hello')
print(mo3)
运行结果如下:
3.用问号实现0次或1次匹配
(mode)?括号里面即为模式,mode出现0次或1次均可成功匹配。
test_regex=re.compile('(fe)?male')
mo1=test_regex.search('This cat is male.')
print(mo1.group())
mo2=test_regex.search('This cat is female')
print(mo2.group())
运行结果如下:
4.用星号匹配0次或多次
(mode)*,mode出现0次或多次均可匹配成功。
test_regex=re.compile('a(ha)*~')
# 匹配0次
mo1=test_regex.search('my blog name is a~')
print(mo1.group())
# 匹配两次
mo2=test_regex.search('my blog name is ahahaha~')
print(mo2.group())
运行结果如下:
5. 用加号匹配一次或多次
(mode)+,mode出现1次或多次均可匹配成功。
test_regex=re.compile('a(ha)+')
# 匹配1次
mo1=test_regex.search('aha')
print(mo1.group())
# 匹配多次
mo2=test_regex.search('ahahaha')
print(mo2.group())
运行结果如下:
6.用花括号匹配特定次数
(mode){n},mode匹配n次即可匹配成功。
# 匹配两次
test_regex=re.compile('a(ha){2}')
mo=test_regex.search('ahaha~')
print(mo.group())
运行结果如下:
另外,还可以给个范围,例如 (mode){n,m},出现n次到m次均可匹配。 (mode){,m}表示0到m次均可匹配。 (mode){n,}表示大于等于n次均可匹配。
test_regex=re.compile('a(ha){2,3}')
mo=test_regex.search('ahahaha')
print(mo.group())
运行结果如下:
我们可以发现ahaha和ahahaha均可匹配,但是正则匹配到的是ahahaha,因为正则表达式的匹配默认是贪心的,会尽量匹配最长的字符串,若想匹配最短的字符串,可在后面加个问号,即(mode){n,m}?。
test_regex = re.compile('a(ha){2,3}?')
mo = test_regex.search('ahahaha')
print(mo.group())
运行结果如下:
三、常用字符分类的缩写代码
缩写字符 | 表示 |
\d | 0-9的任何数字 |
\D | 除0-9的数字以外的任何字符 |
\w | 任何字母、数字或下划线字符 |
\W | 除字母、数字和下划线以外的任何字符 |
\s | 匹配空白字符 |
\S | 除空格、制表符和换行符以为的任何字符 |
-可以表示字母或数字的范围,如[0-9]表示数字0-9,[a-z]表示所有小写字母a-z。
^放在【之后,可以表示非字符类,如[^0-9]表示匹配非0-9的其他字符。
^放在正则表达式开始处,表示必须以正则表达式的模式开始。
$放在正则表达式的结尾处,表示必须以正则表达式的模式结束。
.表示通配符,即匹配除了换行之外的所有字符,代表1个字符。
.*匹配除换行外的所有字符,.代表1个字符,.*代表零次或多次。该表示方法是贪心模式,及尽可能多的匹配字符,若要尽可能少的匹配字符,则在后面加上问号,即.*?。
在re.compile()的第二个参数传入re.DOTALL,.*即可匹配所有字符,包含换行符。
总结:
表示 | 描述 |
? | 匹配0次或1次 |
* | 匹配0次或多次 |
+ | 匹配1次或多次 |
{n} | 匹配n次 |
{n,} | 匹配大于等于n次 |
{,m} | 匹配0-m次 |
{n,m} | 匹配n-m次 |
{n,m}? | 尽可能少的匹配(非贪心模式) |
^haha | 以haha开头 |
haha$ | 以haha结尾 |
. | 匹配1个除换行符外的所有字符 |
.* | 匹配任意个除换行符外的所有字符 |
[aeiou] | 匹配[]内的任意字符 |
[^aeiou] | 匹配非[]内的任意字符 |