正则表达式
正则表达式RE是一种小型的、高度专业化的编程语言,在Python中内嵌,通过re模块实现
正则表达式包括:
字符匹配:
普通字符:大多数字母和字符,如正则表达式test会和字符串“test”完全匹配
元字符 . ^ $ * + ? [] {} \ | ()
RE最重要的就是学习元字符的使用,以实现更多的匹配规则
import re
s= r'abc' #定义正则表达式模式
re.findall(s,str1)
res= r"t[io]p"
res= r"t[^io]p" 匹配非,除外
元字符讲解
[] 用来指定一个字符集:[abc],[a-z],[0-9][a-zA-Z0-9]
元字符在字符集中无效:[akm$]
匹配字符集取反,匹配除外:[^5]
^ 匹配行首,
$ 匹配行尾,行尾被定义为要么是字符串尾,要么是一个换行字符后的任何位置
case
s="helloworld,hello_boy"
r=r"hello"
re.findall(r,s)
>>> re.findall(r,s)
['hello', 'hello']
>>> r1=r"hello*"
>>> re.findall(r1,s)
['hello', 'hello']
>>> r2=r"^hello"
>>> re.findall(r2,s)
['hello']
>>> r3=r"boy$"
>>> re.findall(r3,s)
['boy']
>>>
元字符匹配实战
case
>>> import re
>>> r=r"^abc"
>>> re.findall(r,'abc')
['abc']
>>> re.findall(r,'aa abc')
[]
>>> re.findall(r,'aa ^abc')
[]
>>> re.findall(r,'^abc ^abcd ^abcde')
[]
>>> re.findall(r,'^abc ^abcd ^abcde')
[]
>>> r1=r"\^a"
>>> re.findall(r1,'^abc ^abcd ^abcde')
['^a', '^a', '^a']
\ 反斜杠\后面可以加不同的字符以表示不同特殊意义,也可以用于取消所有的元字符:\[或\\
\d匹配任何十进制数,相当于类[0-9]
\D匹配任何非数字字符,相当于类[^0-9]
\w匹配任何字母数字字符,相当于[a-zA-Z0-9]
\W匹配任何非字母数字字符,相当于[^a-zA-Z0-9]
case
>>> r=r"[0-9]"
>>> re.findall(r,'123456789')
['1', '2', '3', '4', '5', '6', '7', '8', '9']
>>> re.findall(r,'12345 6789')
['1', '2', '3', '4', '5', '6', '7', '8', '9']
>>> r1=r"\d"
>>> re.findall(r1,'12345 6789')
['1', '2', '3', '4', '5', '6', '7', '8', '9']
>>> r2=r"\w"
>>> re.findall(r2,'hsdkf 1234 ^jlk ab23')
['h', 's', 'd', 'k', 'f', '1', '2', '3', '4', 'j', 'l', 'k', 'a', 'b', '2', '3']
>>>
重复*
正则表达式第一功能是能够匹配不定长的字符集,另一个功能室可以指定正则表达式的一部分重复次数, * 指定前一个字符可以被匹配0或任意多次。如 a[bcd]*b匹配"abcbd"
匹配电话号码
r=r"^010-\d{8}" //将前面匹配规则重复{}次数
case
>>> r3=r"a[bcd]*b"
>>> re.findall(r3,'abcbd')
['abcb']
>>> r4=r"^010-\d{8}"
>>> re.findall(r3,'010-29818485')
[]
>>> re.findall(r4,'010-29818485')
['010-29818485']
>>> r5=r"^010-\d{6}"
>>> re.findall(r5,'010-29818485')
['010-298184']
>>> re.findall(r4,'010-298184')
[]
>>> r6=r"^a[bcd]*F$"
>>> re.findall(r6,'adbccdF')
['adbccdF']
>>> re.findall(r6,'aF')
['aF']
>>> r7=r"^a[bcd]{3}F$"
>>> re.findall(r6,'abbbF')
['abbbF']
>>> re.findall(r6,'abddF')
['abddF']
>>>
+ 表示匹配1或多次,注意*与+号不同,*可以匹配0或多,+ 匹配1或多次。
点号,代表任意一个字符
匹配0或1次,通常可用于标识某事物是可选的。比如匹配电话号中间的-,字符串中间的下划线_
case
>>>
>>> r8=r"^010-?\d{8}"
>>> re.findall(r8,'010-29818485')
['010-29818485']
>>> re.findall(r8,'01029818485')
['01029818485']
>>> r9=r"^010-?\d{8}$"
>>> re.findall(r8,'01029818485ab')
['01029818485']
>>> re.findall(r9,'01029818485ab')
[]
>>>
>>> a1=r"hello.world"
>>> re.findall(a1,'hello world')
['hello world']
>>> re.findall(a1,'hello-world')
['hello-world']
>>> re.findall(a1,'helloworld')
[]
>>> re.findall(a1,'hello?world')
['hello?world']
>>>
{m,n} 花括号,其中m,n是十进制数,该限定符意思是至少m~n个重复。忽略m则下边界是0,忽略n上边界为无穷大。
{0,} 等同于 *,{1,} 等同于+,而{0,1}等同于? 非常灵活
re compile
如果某个正则表达式 r“regrexpre” 使用率较高,更好的方式是利用re模块自带的编译compile将正则表达式编译,这样每次re匹配时就不需要re模块解释器翻译了,速度更快。
p_tel = re.compile(r8)
>>> p_tel.findall('01029818485ab')
['01029818485']
>>>
编译之后的re正则,会比未编译的速度快很多。而且编译后还可以选择其他一些参数,例如re.compile()中接受可选的标志参数,常用来实现不同的特殊功能,指定是否区分大小写,让正则更灵活
反斜杠的麻烦----字符串前加“r”反斜杠就不会被任何特殊方式处理
使用re编译后的对象,执行匹配,可以利用re内的方法执行更复杂精确的匹配。---‘RegexObject’实例有一些方法和属性,完整的列表可查阅Python library Reference
match() 决定RE时候在字符串刚开始的位置匹配(在开头位置匹配)
search() 扫描字符串,找到这个RE匹配的位置
findall() 找到这个RE匹配的所有子串,并把他们作为一个列表返回
finditer() 找到这个RE匹配的所有子串,并把他们作为一个迭代器返回
如果没有匹配到的话,match()和search()将返回None,如果成功的话,就会返回一个‘MatchObject’实例。
>>> p_tel.match('01029818485ab')
<_sre.SRE_Match object at 0x0139A838>
>>> p_tel.match('01029818485ab8')
<_sre.SRE_Match object at 0x0139A870>
>>> p_tel.match('0102981ab8485ab8')
>>> 未匹配到,返回None
RE分组 group
case
>>> email = r"\w{3}@\w+(\.com|\.cn)"
>>> re.match(email,'www@wert.com')
<_sre.SRE_Match object at 0x01390560>
>>> re.match(email,'www.ilovepython.cn')
>>> re.match(email,'www@ilovepython.cn')
<_sre.SRE_Match object at 0x013996E0>
>>> re.match(email,'www@ilovepython.org')
>>> re.findall(email,'www@ilovepython.cn')
['.cn']
>>>
分组(re)可以把多种或or关系的放在一起,或进行其他操作,当使用分组后,findall()会优先返回re分组中的匹配结果。re分组的这一特点可以应用与筛选结果,链接,标签等:见下case
>>> s="""hhsdj dskj hello src=csvt yes jdjsds
djhsjk src=123 yes jdsa
src=234 yes
hello src=python yes ksa
"""
>>> s
'hhsdj dskj hello src=csvt yes jdjsds\n djhsjk src=123 yes jdsa\n src=234 yes\n hello src=python yes ksa\n '
>>> import re
>>> r1=r"hello src=.+ yes"
>>> re.findall(r1,s)
['hello src=python yes']
>>> r2=r"hello src=(.+) yes"
>>> re.findall(r2,s)
['python']