Python常用模块——re模块

  有些人在面临问题的时候会想:“我知道,我将使用正则表达式来解决这个问题。”这让他们面临的问题变成了两个。

                                    —— Jamie Zawinski

首先我们对比一下两段代码处理用户输入手机号的不同

1 phone_num = input('请输入手机号:')
2 if len(phone_num) == 11 \
3         and phone_num.isdigit()\
4         and phone_num[:3] in ['130','131','132']:
5     print('hello')
6 else:print('非联通号!')
代码1
1 import re
2 phone_num = input('请输入手机号:')
3 if re.findall('^(130|131|132)[0-9]{8}$',phone_num):
4     print('hello')
5 else:print('非联通号!')
代码2

对比来看代码1比较通俗易懂,代码2看起来有些不太容易理解但是可以使得代码更加的简洁

 1.正则表达式

re模块提供了对正则表达式的支持,学习re模块之前要了解正则表达式:

正则表达式其实是匹配文本片段的模式,最简单的正则表达式是普通的字符串,与自己匹配,可以使用这种匹配行为来完成一下工作:在文本中查找模式,将特定的模式替换为计算得到的值,以及将文本分割为片段。

正则表达式在线测试工具  http://tool.chinaz.com/regex/

1.1通配符

. 匹配除换行符以外的任意字符
\w 匹配字母或数字或下划线
\s 匹配任意的空白符
\d 匹配数字
\n 匹配一个换行符
\t 匹配一个制表符
\b 匹配一个单词的结尾
^ 匹配字符串的开始
$ 匹配字符串的结束
\W 匹配非字母或数字或下划线
\D 匹配非数字
\S 匹配非空白符
a|b 匹配字符a或字符b
() 匹配括号内的表达式,也表示一个组
[...] 匹配字符集中的字符
[^...] 匹配除了字符集中的字符

 1.2字符集

用方括号将一个子串括起来,创建一个所谓的字符集

例如"[a-zA-Z0-9]"与大小写字母以及数字都匹配,但需要注意的是字符集只能匹配一个字符

要排除字符就可以在开头加上^字符,例如"[^abc]"与除a、b和c外的其他任何字符都匹配

字符集 匹配字符 结果 说明
[0123456789] 1 True
在一个字符组里枚举合法的所有字符,字符组里的任意一个字符
和"待匹配字符"相同都视为可以匹配
[0-9] 1 True
也可以用-表示范围,[0-9]就和[0123456789]是一个意思
[a-z] a True
   同样的如果要匹配所有的小写字母,直接用[a-z]就可以表示
[A-Z] A True [A-Z]就表示所有的大写字母

  

1.3量词

* 重复零次或更多次
+ 重复一次或更多次
? 重复零次或一次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次

 

 

 

1.4分组 ()与 或 |[^]

匹配身份证号为15或18位字符串组成,15位为纯数字,首位不能为零。

                       正则            待匹配字符 匹配结果 说明
^[1-9]\d{13,16}[0-9x]$ 53010219200508011x 53010219200508011x 虽可匹配但存在问题
^[1-9]\d{14}(\d{2}[0-9x]$)? 53010219200508011x 53010219200508011x 括号内为子模式,子模式后加量词
([1-9]\d{16}[0-9x]|[1-9]\d{14}) 53010219200508011x 53010219200508011x 括号内加"|",变为二选一模式,先匹配前面后匹配后面

 

 

 

 

1.5 特殊字符进行转义

普通字符与自己匹配,但特殊字符情况不同,要让特殊字符与普通字符一样就要对其进行转义:在正则前加"\"

请注意,为表示模式re要求的单个反斜杠,需要在字符串中写两个反斜杠,让解释器对其转义,包含两层含义,解释器执行的转义和模块re进行的转义

当然可以使用原始字符串,如r'\d'

>>> import re

>>> print(re.findall('\\\\d', '\\d'))  # 匹配字符"\d"时,正则表达为"\\d",然后Python还要对其中两个斜杠在进行转义,最终规则表达式为"\\\\d"
['\\d']

>>> print(re.findall(r'\\d',r'\d')) # 使用原始字符串省去不必要的麻烦
['\\d']

1.6 贪婪和非贪婪匹配 

 贪婪匹配:在满足匹配时,匹配尽可能长的字符串,默认情况下,采用贪婪匹配

加上"?"变为非贪婪匹配

*? 重复任意次,但尽可能少重复
+? 重复1次或更多次,但尽可能少重复
?? 重复0次或1次,但尽可能少重复
{n,m}? 重复n到m次,但尽可能少重复
{n,}? 重复n次以上,但尽可能少重复

一般这样使用时要加上结尾条件,否则只会匹配量词的最少重复次数
你.*? 你好吗
你.*?吗 你好吗你真的好吗

你好吗
你真的好吗

 

 

 

2.模块re的常用函数

函数 描述
compile(pattern, flags=0) 根据包含正则表达式的字符串创建模式对象
escape(string) 对字符串中的所有正则表达式的特殊字符进行转义
findall(pattern, string, flags=0) 返回一个列表,其中包含字符串中的所有与正则模式匹配的子串
search(pattern, string, flags=0) 在字符串中查找模式
split(pattern, string, maxsplit=0, flags=0) 根据模式来分割字符串
sub(pattern, repl, string, count=0, flags=0) 将字符串中与模式匹配的子串替换为 repl
match(pattern, string, flags=0) 在字符串开头查找模式
subn(pattern, repl, string, count=0, flags=0) 将字符串中与模式匹配的子串替换为 repl,返回元组,元组包含替换后结果和替换次数
finditer(pattern, string, flags=0) 返回一个包含结果的迭代器

 

 

 

 

 

 

 

 

 

 

print(re.findall('','你好你是')) # ['你', '你']

ret = re.search('','好是') # 找到后需要调用group()方法,找不到返回None,None不能调用group()方法
if ret:
    print(ret.group())

ret = re.match('','ni好你是') # 和search用法类似
if ret:
    print(ret.group())

ret = re.split('b','abc') # 按“b”分割字符串
print(ret) # ['a', 'c']

ret = re.split('[ad]','adbcde') # 先按“a”分割,再按“b”分割
print(ret) 

print(re.sub('\d','$','zhao123'))
print(re.subn('\d','$','zhao123'))

obj = re.compile('你好')
ret = obj.findall('你好吗')
print(ret)

ret = re.finditer('你好','你好吗你好')
print(ret.__next__().group())




 

猜你喜欢

转载自www.cnblogs.com/zhao1126/p/9508937.html