re模块:正则表达式
正则表达式主要用到的是re模块
模块方法
re
模块在使用的时候要注意,有的函数使用后返回的是一个对象,比如re.search(),re.match()
,这些函数都是使用group()
函数来返回结果,而有的函数在使用后直接返回结果,比如`re.split(),re.findall
`
result = re.search()
在字符串中搜索, 注意,搜索的字符串必须写成原始字符串,只能搜索出第一个匹配
>>> import re
>>> re.search(r'hello','hello,world')
<_sre.SRE_Match object; span=(0, 5), match='hello'>
result.group()
re.search()
方法返回的是一个匹配对象而不是字符串,如果要将匹配对象转换成字符串,就要用到这个方法
>>> result = re.search(r'hello','hello,world')
>>> result.group()
'hello'
>>> result
<_sre.SRE_Match object; span=(0, 5), match='hello'>
如果正则表达式里面的内容存在子组,那么子组会将里面的内容进行捕获通过在group里面设置序号,可以提取到对应捕获的字符串
>>> result = re.search(r'(w+)(w+)','hello,world hello')
>>> result.group()
'hello'
>>> result.group(1)
'hell'
>>> result.group(2)
'o'
result.start()
返回匹配的开始的位置
result.end()
返回匹配的结束的位置
result.span()
返回匹配的我]范围
>>> result.start()
0
>>> result.end()
5
>>> result.span()
(0, 5)
re.match(pattern,string,flag = 0)
检查string是否存在一个和pattern匹配的前缀,也就是从string开头开始就和patterny匹配成功是返回相应的match对象,否则返回None
>>> result = re.match(r'how','hello how are you')
>>> result
>>> result = re.match(r'how','how are you')
>>> result
<_sre.SRE_Match object; span=(0, 3), match='how'>
>>> result.group()
'how'
re.split(pattern,string,maxsplit=0,flag=0)
函数返回分割得到的字符串的列表
>>> result = re.split(r'how','hello how are you')
>>> result
['hello ', ' are you']
re.findall()
匹配所有找到的字符串,把他们打包成列表返回
>>> result = re.findall(r'how','hello how are you how ')
>>> result
['how', 'how']
re.compile()
编译正则表达式(如果你需要重复的使用某个正则表达式,则需要将该正则表达式编译成模式对象)
>>> p = re.compile(r'[A-Z]')
>>> p.search('ksdjfhaskKJHKJHJjhJhhj')
<_sre.SRE_Match object; span=(9, 10), match='K'>
>>> result = p.search('ksdjfhaskKJHKJHJjhJhhj')
>>> result.group()
'K'
>>> result = p.match('AlksdjSkF')
>>> result.group()
'A'
>>> p.findall('lskdFlskdIljalsdkH')
['F', 'I', 'H']
>>> p.split('lskdFlskdIljalsdkH')
['lskd', 'lskd', 'ljalsdk', '']
正则表达式表示方法
正则表达式是通过一个元字符构成一个模式,然后通过这个模式来匹配出很多字符串中符合这个模式的字符串
. ^ $ | 元字符
. 表示除换行符以外的任意字符
^ 表示只匹配字符串开头的位置
$ 表示只匹配字符串结尾的位置
| 表示逻辑或
>>> import re
>>> ret1=re.findall('李.','李爽
alex
李四
egon
alvin
李二')
>>> ret2=re.findall('^李.','李爽
alex
李四
egon
alvin
李二')
>>> ret3=re.findall('李.$','李爽
alex
李四
egon
alvin
李二')
>>> ret1
['李爽', '李四', '李二']
>>> ret2
['李爽']
>>> ret3
['李二']
*+?{} 表示重复
* 零到无穷次
+ 一到无穷
? 0-1次
{} 指定次数
的奥义
-
将元字符去除其特殊功能
-
将一些普通符号转换成特殊意义的符号
匹配字符
A:匹配输入字符串的开始位置,和^用法一样 Z:匹配输入字符串的结束位置,用法和$一样 b :匹配一个单词边界,单词被定义为unidcode的字母数字或下横线字符 d 匹配任何十进制数; 它相当于类 [0-9]。 D 匹配任何非数字字符; 它相当于类 [^0-9]。 s 匹配任何空白字符; 它相当于类 [ tnrfv]。 S 匹配任何非空白字符; 它相当于类 [^ tnrfv]。 w 匹配任何字母数字字符; 它相当于类 [a-zA-Z0-9_]。 W 匹配任何非字母数字字符; 它相当于类 [^a-zA-Z0-9_] b 匹配一个特殊字符边界,比如空格 ,&,#等
匹配数字
如果 后面的数字为(1~99),表示引用序号对应的子组所匹配的字符串 如果 后面的数字为零或者三位数字(八进制),表示这个八进制对应ASC码的字符
转义
转义符号:正则表达式支持大部分Python字符串的转义符号: a,b,f,n,r,t,u,U,v,x,\
-
如果在方括号里面不会失去其特殊含义
-
如果想要表示,则在前面再加一个,应该这样表示
()的奥义:分组
使用小括号指定一个子表达式后,匹配这个子表达式的文本(也就是此分组捕获的内容)可以在表达式或其它程序中作进一步的处理。默认情况下,每个分组会自动拥有一个组号,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推。
使用小括号指定子表达式匹配时是按照所有的模式匹配,但是返回显示的时候只显示括号内匹配的内容
(?:…)
非捕获组,即该子组匹配的字符串无法从后边获取
(?P<name>.....)
给此分组命名
>>> result = re.search(r'(w+)(w+)','hello,world hello')
>>> result.group()
'hello'
>>> result.group(1)
'hell'
>>> result.group(2)
'o'
[…]
生成一个字符类,也就是一个集合,里面包含的所有字符都会失去其特殊性除了几个特殊的字符,这个字符类
这个字符类只会选择括号里面所有字符的一个进行匹配
如果直接是一个点,则会匹配除了换行符以外的所有字符,反斜杠加点则匹配点本身,而方括号里面的点会失去其特殊性,也会匹配点本身
- 如果出现在字符串中间则表示字符范围描述,如果出现在首位则表示普通字符
>>> re.findall(r'[a-z]','welkj1234sdkjfHIK')
['w', 'e', 'l', 'k', 'j', 's', 'd', 'k', 'j', 'f']
特殊字符中仅仅反斜杠保持原来的特殊意义,其他的字符都作为普通字符匹配
^ 如果出现在方括号中标志除了类里面的字符,其他的都匹配,脱字符只能放在前面,如果放后面则表示匹配脱字符本身
一般情况下,* , + 和 ? 的匹配模式是贪婪模式(即会尽可能多的匹配符合规则的字符串) *? ,+? 和 ?? 会表示启用对应的非贪婪模式
正则表达式常用组合(如果m能匹配字符串s,n能匹配字符串t,):
-
正则表达式里的普通字符只与该字符本身匹配
-
mn:匹配字符串拼接s+t
-
m|n:既能匹配s,也能匹配t
-
m*:能匹配空串、s、s+s、s+s+s等
由于字符范围比较特殊,比如月份,需要考虑的很多,比如前面一位取0时,后面一位取0-9,而当前面一位取1时,后面一位只能取012,所以应该分情况考虑
# 年份
s4 = '1990-07-12lskd2016-09-35jfls1989-12-30laksdjf2931989-13-14f8478-32098-34-34-5-123'
p4 = re.compile(r'[12]d{3}-(?:0d|1[012])-(?:[012]d|3[01])')
print(p4.findall(s4))
['1990-07-12', '1989-12-30']