本文最后更新于:14 天前
正则
在实际的应用中,我们会经常得到用户的输入,在得到用户的输入之后,需要我们对输入进行判断时候合法,比如判断输入的手机号码,从形式上来看是争取的呢?
mu = input('请输入电话号码:')
def phone_number(st):
st = str(st)
if len(st) == 11 and st.startswith('1') and st.isdigit() :
return True
else:
print('Phone Number Error')
return False
print(phone_number(mu))
请输入电话号码:12332112345
True
那有什么简单的方法呢?
正则搜索
match
import re
a = '12345678900'
rm = re.match(r'1\d{10}',a)
print(rm)
<_sre.SRE_Match object; span=(0, 11), match='12345678900'>
search
import re
a = '12345678900'
rs = re.search(r'1\d{10}',a)
print(rs)
<_sre.SRE_Match object; span=(0, 11), match='12345678900'>
通过对比,可以很明显的发现,下面这种方式能够简单快捷的匹配出电话号码
总结
正则表达式:正则表达式是一种通用的用来简洁表达一组字符串的表达式,因此,正则表达式是和python无关的,在其他的语言或者不同的系统中,是通用的。
匹配:通过正则表达式就可以去匹配现有的字符串。
应用:通过正则匹配,可以迅速的过滤出我们需要的全部或者一部分字符串,查找文本中的特质值(如:病毒)等等。
元字符
正则表达式该如何书写呢?
观察如下两个例子:
In [3]: re.search('a', 'abc')
Out[3]: <_sre.SRE_Match object; span=(0, 1), match='a'>
In [5]: re.search('.', 'ab.cd.de')
Out[5]: <_sre.SRE_Match object; span=(0, 1), match='a'>
在第一个例子中,可以匹配出a
但是下面这个不能匹配,但是下面这个没有匹配出点,而是匹配到 a
这个 . 不是不能匹配到点,而是匹配任意字符,这个点已经被赋予了特殊的含义, .(点)就是一个元字符
正因为有这些元字符的存在,正则表达式才变得强大.
\b
In [23]: re.search('\bs\b', 'abcdsd s we')
In [24]: re.search(r'\bs\b', 'abcdsd s we')
Out[24]: <_sre.SRE_Match object; span=(7, 8), match='s'>
在正则中,加上r 去掉字符串的转义,以免影响正则的使用
\b匹配一个单词边界,也就是指单词和空格间的位置。
.
In [26]: re.search(r'.', 'abcdsd s we')
Out[26]: <_sre.SRE_Match object; span=(0, 1), match='a'>
In [27]: re.search(r'.', '\nabcdsd s we')
Out[27]: <_sre.SRE_Match object; span=(1, 2), match='a'>
匹配除换行符之外的所有的字符
\d
In [28]: re.search(r'\d',r'abc141342d')
Out[28]: <_sre.SRE_Match object; span=(3, 4), match='1'>
匹配0~9的数字
\s
In [30]: re.search(r'\s',r'abc 141342d')
Out[30]: <_sre.SRE_Match object; span=(3, 4), match=' '>
匹配任意的空白符,包括空格,制表符(Tab),换行符等
\w
In [31]: re.search(r'\w',r'abc 141342d')
Out[31]: <_sre.SRE_Match object; span=(0, 1), match='a'>
匹配字母或数字或下划线或汉字等 \b 表示单词的边界
In [32]: re.search(r'\bc\b',r'abc c 342d')
Out[32]: <_sre.SRE_Match object; span=(4, 5), match='c'>
In [33]: re.search(r'\bbcb\b',r'abc bcb 342d')
Out[33]: <_sre.SRE_Match object; span=(4, 7), match='bcb'>
\.
In [34]: re.search(r'\.',r'ab.c .bcb 342d')
Out[34]: <_sre.SRE_Match object; span=(2, 3), match='.'>
表示匹配点号本身
\D、\S、\W、\B
In [35]: re.search(r'\D','abc.1213')
Out[35]: <_sre.SRE_Match object; span=(0, 1), match='a'>
In [36]: re.search(r'\S','abc.1213')
Out[36]: <_sre.SRE_Match object; span=(0, 1), match='a'>
In [37]: re.search(r'\W','abc.1213')
Out[37]: <_sre.SRE_Match object; span=(3, 4), match='.'>
In [38]: re.search(r'\B','abc.1213')
Out[38]: <_sre.SRE_Match object; span=(1, 1), match=''>
是与小写的相反的作用
\D
In [39]: re.search(r'\D','abc.1213')
Out[39]: <_sre.SRE_Match object; span=(0, 1), match='a'>
除了数字以外的字符
^
In [41]: re.search(r'^ab',r'abc 141342d')
Out[41]: <_sre.SRE_Match object; span=(0, 2), match='ab'>
脱字符,匹配输入字符串的开始的位置
$
In [42]: re.search(r'd$',r'abc 141342d')
Out[42]: <_sre.SRE_Match object; span=(10, 11), match='d'>
匹配输入字符串的结束位置
{}
In [43]: re.search(r'\d{1,3}',r'abc 141 qw 342d') # 对象,找到一个就不找了
Out[43]: <_sre.SRE_Match object; span=(4, 7), match='141'>
In [44]: re.findall(r'\d{1,3}',r'abc 141 qw 342d') #列表,全部找出来
Out[44]: ['141', '342']
In [45]: re.findall(r'\d{1,}',r'abc 141 qw 34325252d')
Out[45]: ['141', '34325252']
In [46]: re.findall(r'\d{,5}',r'abc 141 qw 34325252d')
Out[46]: ['', '', '', '', '141', '', '', '', '', '34325', '252', '', '']
In [47]: re.findall(r'\d{0,3}',r'abc 141 qw 34325252d')
Out[47]: ['', '', '', '', '141', '', '', '', '', '343', '252', '52', '', '']
{M,N} M和N 为非负整数,其中M<=N 表示前面的匹配M~N次
{M,} 表示需要匹配M次
{,N} 等价于{0~N}
{N} 表示需要匹配N次
*
In [49]: re.findall(r'\d*',r'abc 141 qw 34325252d')
Out[49]: ['', '', '', '', '141', '', '', '', '', '34325252', '', '']
In [50]: re.findall(r'\d{0,}',r'abc 141 qw 34325252d')
Out[50]: ['', '', '', '', '141', '', '', '', '', '34325252', '', '']
匹配前面的子表达式零次或多次,等价于{0,}
+
In [51]: re.findall(r'\d+',r'abc 141 qw 34325252d')
Out[51]: ['141', '34325252']
In [52]: re.findall(r'\d{1,}',r'abc 141 qw 34325252d')
Out[52]: ['141', '34325252']
匹配前面的子表达式一次或多次,等价于{1,}
?
In [57]: re.findall(r'\d{0,1}',r'ab5252d')
Out[57]: ['', '', '5', '2', '5', '2', '', '']
In [58]: re.findall(r'\d?',r'ab5252d')
Out[58]: ['', '', '5', '2', '5', '2', '', '']
匹配前面的子表达式零次或一次,等价于{0,1}
贪婪与非贪婪
*?、+?
In [61]: re.findall(r'\d*?',r'ab5252d')
Out[61]: ['', '', '', '', '', '', '', '']
In [62]: re.findall(r'\d+?',r'ab5252d')
Out[62]: ['5', '2', '5', '2']
In [65]: st ="<html>aaaa</html><td>bbbb</td>"
In [66]: re.findall(r'<.*>',st)
Out[66]: ['<html>aaaa</html><td>bbbb</td>']
In [67]: re.findall(r'<.*?>',st)
Out[67]: ['<html>', '</html>', '<td>', '</td>']
在非贪婪模式下,始终找最短匹配
[]字符集合
[] 字符类,将要匹配的一类字符集放在[]里面
In [68]: re.findall(r'[\d]',r'abc 141 qw 34325252d')
Out[68]: ['1', '4', '1', '3', '4', '3', '2', '5', '2', '5', '2']
In [69]: re.findall(r'[0-9]',r'abc 141 qw 34325252d')
Out[69]: ['1', '4', '1', '3', '4', '3', '2', '5', '2', '5', '2']
In [70]: re.findall(r'[a-z]',r'abc 141 qw 34325252d')
Out[70]: ['a', 'b', 'c', 'q', 'w', 'd']
[ . ? * ( ) {} ] 匹配里面的这些符号
[0-9] 匹配0到9的数字相当于\d
[^\d] 匹配除数字以外的字符,相当于\D取反的意思
[a-z] 匹配所有的小写字母
[^a-z] 匹配非小写字母
| 相当于或(or)分支条件
()分组匹配
() 分组,将要匹配的一类字符集放在()组成一个小组
In [75]: re.findall(r'(32)',r'abc 141 qw 34325252d')
Out[75]: ['32']
In [76]: re.findall(r'a(3|2)',r'a3 a2 a23 ')
Out[76]: ['3', '2', '2']
In [77]: re.findall(r'a([32])',r'a3 a2 a23 ')
Out[77]: ['3', '2', '2']
分组匹配匹配() 内的字符串组合
re模块
compile
编译正则表达式为模式对象
当正则表达式多次使用,可以采用这种方式
In [78]: r = re.compile(r'\das')
In [79]: r.findall('1as234')
Out[79]: ['1as']
sub
字符串替换
In [80]: re.sub('i','o','pythin***pythin',1)
Out[80]: 'python***pythin'
In [81]: re.sub('i','o','pythin***pythin',2)
Out[81]: 'python***python'
In [82]: re.sub('i','o','pythin***pythin')
Out[82]: 'python***python'
match
从字符串开始位置匹配
In [83]: re.match(r'\d','123ad')
Out[83]: <_sre.SRE_Match object; span=(0, 1), match='1'>
In [84]: re.match(r'\d','a123ad')
group
得到匹配到的元素
In [94]: re.search(r'\d{1,3}',r'abc 141 qw 342d')
Out[94]: <_sre.SRE_Match object; span=(4, 7), match='141'>
In [95]: li = re.search(r'\d{1,3}',r'abc 141 qw 342d')
In [96]: li.group()
Out[96]: '141'
start
得到开始位置
In [97]: li.start()
Out[97]: 4
end
得到结束位置
In [98]: li.end()
Out[98]: 7
span
得到位置范围
In [99]: li.span()
Out[99]: (4, 7)
注意:
这几个方法在search中也存在
扩展
在re中也有和字符串一样的split方法
In [85]: re.split(r'\s',' cee')
Out[85]: ['', 'cee']
In [86]: re.split(r'\s','aa bb cc dd')
Out[86]: ['aa', 'bb', 'cc', 'dd']
In [87]: re.split(r'[\s|c]','aa bb c dd ee')
Out[87]: ['aa', 'bb', '', '', 'dd', 'ee']
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!