正则表达式
正则表达式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']