re模块
正则表达式 —— 字符串匹配的
举例:判断一串数字是否是手机号。
未使用正则表达式:
while True:
phone_number = input('please input your phone number : ')
if len(phone_number) == 11 \
and phone_number.isdigit()\
and (phone_number.startswith('13') \
or phone_number.startswith('14') \
or phone_number.startswith('15') \
or phone_number.startswith('18')):
print('是合法的手机号码')
else:
print('不是合法的手机号码')
使用正则表达式:
import re
phone_number = input('please input your phone number : ')
if re.match('^(13|14|15|18)[0-9]{9}$',phone_number):
print('是合法的手机号码')
else:
print('不是合法的手机号码')
re模块的方法:findall,search,match,split,sub,subn,finditer
findall:
返回所有满足匹配条件的结果,放在列表里
ret = re.findall('[a-z]+', 'eva egon yuan')
print(ret)
search:
从前往后,找到一个就返回,返回的变量需要调用group才能拿到结果
如果没有找到,那么返回None,调用group会报错
ret = re.search('a', 'eva egon yuan')
if ret:
print(ret.group())
match:
match是从头开始匹配,如果正则规则从头开始可以匹配上,就返回一个变量。
匹配的内容需要用group才能显示
如果没匹配上,就返回None,调用group会报错
ret = re.match('[a-z]+', 'eva egon yuan')
if ret:
print(ret.group())
split: 分割
ret = re.split('[ab]', 'abcd')
# 先按'a'分割得到''和'bcd',在对''和'bcd'分别按'b'分割
print(ret) →输出:['', '', 'cd']
sub: 替换
ret = re.sub('\d', 'H', 'eva3egon4yuan4',1)
#将数字替换成'H',参数1表示只替换1个
print(ret) #evaHegon4yuan4
subn: 返回元组(替换的结果,替换了多少次)
ret = re.subn('\d', 'H', 'eva3egon4yuan4')
#将数字替换成'H'
print(ret)→输出:('evaHegonHyuanH', 3)
**compile:**将正则表达式编译成为一个 正则表达式对象
obj = re.compile('\d{3}')
#将正则表达式编译成为一个 正则表达式对象,规则要匹配的是3个数字
ret = obj.search('abc123eeee') #正则表达式对象调用search,参数为待匹配的字符串
print(ret.group())→输出: 123
ret = obj.search('abcashgjgsdghkash456eeee3wr2')
#正则表达式对象调用search,参数为待匹配的字符串
print(ret.group()) →输出: 456
finditer: 返回一个存放匹配结果的迭代器
ret = re.finditer('\d', 'ds3sy4784a') #finditer返回一个存放匹配结果的迭代器
print(ret) →输出:<callable_iterator object at 0x10195f940>
# print(next(ret).group()) #查看第一个结果
# print(next(ret).group()) #查看第二个结果
# print([i.group() for i in ret]) #查看剩余的左右结果
for i in ret:
print(i.group())
#输出:
3
4
7
8
4
正则表达式:能根据字符串给出正则表达式的网址:tool.china2.com/regex/
import re
ret = re.search('^[1-9](\d{14})(\d{2}[0-9x])?$','110105199912122277')
print(ret.group())
print(ret.group(1))
print(ret.group(2))
#输出:
110105199912122277
10105199912122
277
import re
ret = re.findall('www.(baidu|oldboy).com', 'www.oldboy.com')
print(ret) →输出: ['oldboy']
#这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可
ret = re.findall('www.(?:baidu|oldboy).com', 'www.oldboy.com')
print(ret) → ['www.oldboy.com']
ret=re.split("\d+","eva3egon4yuan")
print(ret) →输出: ['eva', 'egon', 'yuan']
ret=re.split("(\d+)","eva3egon4yuan")
print(ret) →输出: ['eva', '3', 'egon', '4', 'yuan']
各种字符与含义:书本《正则指引》
元字符
符号 | 含义 |
---|---|
. | 除了换行符以外的任意字符串,如str.→str+后一字符 |
\w | 字母、数字、下划线 |
\s | 任意空白符 |
\d | 数字,[\d]+:多个多位数字的匹配,不会一个一个匹配 |
\W | 非字母、数字、下划线 |
\D | 非数字 |
\S | 非空白符 |
\n | 一个换行符 |
\t | 制表符(Tab) |
\b | 匹配单词结尾,配合‘.’ 一起使用 |
^ | 匹配以……开头,如^e:以e开头的 |
$ | 匹配字符串的结尾,一定写在最后 |
a/b | 含a或b ,abc/ab:先匹配abc在匹配ab,注意顺序 |
() | 分组,要对组合的字符进行匹配时 |
[…] | 匹配字符组中的字符 |
[^…] | 匹配除了字符组中字符的所有字符(非),写在开头 |
量词(放后面):量词仅约束紧跟着的前一个字符
符号 | 含义 |
---|---|
* | 重复零次或更多次(贪婪匹配),如\d*:所有的连续数字 |
+ | 重复一次或者更多次 |
? | 重复零次或一次,一个一个匹配 ,可将贪婪转为非贪婪,也叫惰性匹配,放在分组(?…)中取消分组优先 |
{n} | 重复n次 |
{n,} | 重复n次或者更多次 |
{n,m} | 重复n到m次 |
字符组
在同一位置可能出现的各种字符组成了一个字符组,在正则表达式中用[]表示。
符号 | 含义 |
---|---|
[0123456789]/[0-9] | 数字,字符组里的数据 |
[a-z] | 小写字母 |
[A-Z] | 大写字母 |
[0-9 a-f A-F] | 可以匹配数字,大小写姓氏a-f,用来验证十六进制字符 |
转义符
符号 | 含义 |
---|---|
r’\n’ | r能取消\的转义 |
贪婪匹配
符号 | 含义 |
---|---|
<.*> | 贪婪:先匹配所有,再匹配结尾的‘>’ |
<.*?> | 非贪婪:一直匹配,如有‘>’就结束 |
*? | 重复任意次,但尽可能少重复 |
+? | 重复1次或更多次,但尽可能少重复 |
?? | 重复0次或者1次,但尽可能少重复 |
{n,m}? | 重复n到m次,但尽可能少重复 |
{n,}? | 重复n次以上,但尽可能少重复 |
.*? | 取尽量少的任意字符,如.*?x:匹配x之前一直匹配 |