目录
re.match(pattern, string, flags=0)方法
re.search(pattern, string, flags=0)方法
re.findall(pattern, string, flags=0)方法
re.finditer(pattern, string, flags=0)方法
re.split(pattern, string, maxsplit=0, flags=0)方法
re.sub(pattern, repl, string, count=0, flags=0)方法
re.subn(pattern, repl, string, count=0, flags=0)方法
正则表达式总结
正则表达式是一个特殊的字符序列,描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串;可以做精确匹配,模糊匹配,进行字符串替换、切割,尤其是在分析日志时用的比较多。
python处理正则表达式的模块是re模块,它是python语言中拥有全部的正则表达式功能的模块;正则表达式由一些普通字符和一些元字符组成,普通字符包括大小写的字母,数字和打印符号,而元字符是具有特殊含义的字符;
1.正则表达式模式
正则表达式大致的匹配过程是: 拿正则表达式依次和字符串做比较,如果每一个字符都匹配,则匹配成功,只要有一个匹配不成功的字符,则匹配不成功。
需要注意的是:
由于正则表达式通常包含反斜杠等特殊字符,所以我们最好使用原始字符串来表示他们。如:r’\d’,等价于’\\d’,表示匹配一个数字。
Python正则表达式中,数量词默认都是贪婪的,它们会尽力尽可能多的去匹配 满足的字符,但是如果我们在后面加上问号“?”,就可以屏蔽贪婪模式,表示匹配尽可能少的字符。
2.特殊表达式含义
符号 | 含义 | 举例 |
一般字符(匹配自身) | ||
.(点) | 匹配除换行符之外的任意一个字符 | a.c可以匹配abc |
\(反斜杠) | 转义一个特殊的字符,使这个字符表示原来字面上的意思。如"\$",表示原字符$,而不是正则表达式中表示匹配行尾的意思。 | a\.c匹配a.c |
预定义字符集(可以写在[]中) | ||
[...](方括号) | 匹配括号中出现的任意单个字符 | a[123]b匹配a1b、a2b、a3b |
[^...] | 不匹配方括号中列出的单个字符(注意只能针对单个字符) | [^ab]匹配除a和b之外的字符 |
\d | 匹配任意一个数字,范围[0-9] | a\dc可以匹配a1c、a2c等 |
\D | 匹配任意一个非数字字符,等价于[^\d] | 1\D2可匹配1a2等 |
\s | 匹配任意一个空白字符,如[空格\t\r\n\v\f] | a\sf可以匹配a f等 |
\S | 匹配任意一个非空白字符,等价于[^\s] | a\Sg可以匹配agg等 |
\w | 匹配一个字母或数字,字符范围[a-zA-Z0-9] | 1\w2可以匹配112、1a2等 |
\W | 匹配一个非字母或非数字,等价于[^\w] |
|
数量字符集(用在字符或分组符(...)之后,非贪婪匹配*? +? | ||
*(星号) | 匹配前一个字符0次1次或多次 | abc*可以匹配ab,abc,abcc等 |
+(加号) | 匹配前一个字符1次或多次 | abc+可以匹配abc,abcc等 |
?(问号) | 匹配前一个字符0次或多次 | abc?可以匹配ab,abc |
{m} | 匹配前一个字符m次 | qc{3}匹配结果qccc |
{m,n} | 匹配前一个字符m到n次; | 1{2,5}c匹配结果11c,111c,1111c,11111c |
边界匹配符 | ||
^(托字符) | 匹配字符串开头,如果是多行则匹配每一行的开头。在[...]中,^表示否定,如非数字[^0-9] | ^123匹配123 |
$(美元符) | 匹配字符串或一行的结尾,如果是多行则匹配每一行的结尾 | abc$匹配abc |
\A | 仅匹配字符串的开始 | \A12AC匹配12AC |
\b | 匹配一个单词的边界,也就是单词和空格间的位置。如"st",可以匹配"a test of"中的"st",但不匹配"tester"中的"st" | re.search(r"st\b","a test of")有匹配结果 |
\B | [^\b],表示匹配非单词边界 | re.search(r"st[^\b]","a test of ")匹配'st ' |
\Z | 匹配字符串结束,如果存在换行,只匹配到换行前的结束符 | re.search(r"\w+\Z","ABC")匹配"ABC" |
逻辑匹配符 | ||
|(或) | 表达左右正则表达式任意匹配一个,如果左边的表达式匹配上了,匹配结束,不再匹配右边的表达式; | re.search(r"12|43","1243")匹配"12" |
分组匹配 | ||
(...) | 后向引用。用()括起来的正则表达式将被作为一个分组,从正则表达式的左边依次算起,有多少个左括号"(",就有多少个分组,分组的编码从1依次加1,无论括号中是否嵌套括号。并且分组表达式作为一个整体,后可接数量词。 | (xyz){2}满足xyzxyz |
\(number) | 引用分组匹配到的分组编号为<number>的字符串 | 如:\1...\9 |
(?P<name>...) | 命名分组,除了默认的分组编号外再指定一个别名分组,注意:P是大写 | re.search(r"(?P<数字>\d+)","sad23").group("数字") |
(?P=name) | 引用别名为name的分组匹配,这个是在正则表达式中引用,表示匹配重复的字符串,也可以是使用编号引用。注意:P是大写,引用分组时内容需一致 |
|
特殊匹配符(不能作为分组使用) | ||
(?<!pattern) | 前向否定,表示在前面(?!pattern)匹配的内容不存在,它后面的正则才生效,返回后面正则匹配的内容 | re.search(r"(?<!abc)\d+","abc12")匹配结果为"2" |
(?!pattern) | 后向否定,表示在后面(?!pattern)匹配的内容不存在,它前面的正则才生效,返回前面正则匹配的内容 | re.search(r"\d+(?!\w+)","23ds 4323")匹配结果为"4323" |
(?<=pattern) | 前向肯定,表示在前面(?<=pattern)匹配的内容存在,它后面的正则才生效,返回后面正则匹配的内容 | re.search(r"(?<=[abc])\d+","abc123").group()匹配结果为"123" |
(?=pattern) | 后向肯定,表示在后面(?=pattern)匹配的内容存在,它前面的正则才生效,返回前面正则匹配的内容 | re.search(r"\d+(?=abc)","abc123abc").group()匹配结果为"123" |
2.1 .(点)
匹配除换行符之外的任意一个字符,在DOTALL模式中是可以匹配换行符
>>> import re
>>> re.match(r".","abc")
<_sre.SRE_Match object; span=(0, 1), match='a'> #匹配结果对象
>>> re.match(r"..","abc")
<_sre.SRE_Match object; span=(0, 2), match='ab'>
span :匹配结果的起始位置和结束位置,开区间
>>> re.match(r"....","abc")
>>> print (re.match(r"....","abc"))
None
>>> print (re.match(r"..","a\nc"))
None
>>> print (re.match(r"..","a\nc",re.DOTALL))
<_sre.SRE_Match object; span=(0, 2), match='a\n'>
2.2 \(斜杠)
转义符,转义一个特殊的字符
>>> print (re.match(r"\..",".a\nc",re.DOTALL))
<_sre.SRE_Match object; span=(0, 2), match='.a'>
>>> print(re.match(r"\\","\\a\nc"))
<_sre.SRE_Match object; span=(0, 1), match='\\'>
2.3 [...](方括号)
匹配括号中出现的任意单个字符;
>>> print (re.match(r"[abc]","ac"))
<_sre.SRE_Match object; span=(0, 1), match='a'>
>>> print (re.match(r"[abc]","bc"))
<_sre.SRE_Match object; span=(0, 1), match='b'>
>>> print (re.match(r"[abc]","cc"))
<_sre.SRE_Match object; span=(0, 1), match='c'>
2.4 [^...]
在方括号中表示非的意思;不匹配方括号中列出的单个字符
>>> print (re.match(r"[^abc]","cc"))
None
>>> print (re.match(r"[^abc]","hc"))
<_sre.SRE_Match object; span=(0, 1), match='h'>
2.5 ^
不在方括号中,表示匹配字符串开头
>>> print(re.search(r"abc","sssssabc"))
<_sre.SRE_Match object; span=(5, 8), match='abc'>
>>> print(re.search(r"^abc","sssssabc"))
None
>>> re.search(r"^abc","dddabc") #没有匹配结果
>>> re.search(r"^abc","abcdddabc")
<_sre.SRE_Match object; span=(0, 3), match='abc'>
>>> re.search(r"^\d+","1234s3254f")
<_sre.SRE_Match object; span=(0, 4), match='1234'>
2.6 \d
匹配字符串中的任意一个数字,范围为[0-9]
>>> re.match(r"\d","12")
<_sre.SRE_Match object; span=(0, 1), match='1'>
2.7 \D
匹配任意一个非数字字符,等价于[^\d]
>>> re.match(r"\D+","a123").group()
'a'
>>> re.match(r"\D+","abc123").group()
'abc'
2.8 \s
匹配任意一个空白字符,如[空格\t\r\n\v\f]
>>> re.match(r"\s"," 2")
<_sre.SRE_Match object; span=(0, 1), match=' '>
>>> re.match(r"\s","\n2")
<_sre.SRE_Match object; span=(0, 1), match='\n'>
>>> re.match(r"\s"," 2")
<_sre.SRE_Match object; span=(0, 1), match='\t'>
2.9 \S
匹配任意一个非空白字符,等价于[^\s]
>>> re.findall(r"\S+","\nAS\tet 32")
['AS', 'et', '32']
>>> "".join(re.findall(r"\S+","\nAS\tet 32"))
'ASet32'
2.10 \w
匹配一个数字、字母和下划线,字符范围:[a-zA-Z0-9]
>>> re.match(r"\w","2we")
<_sre.SRE_Match object; span=(0, 1), match='2'>
>>> re.match(r"\w","we")
<_sre.SRE_Match object; span=(0, 1), match='w'>
>>> re.match(r"\w","_we")
<_sre.SRE_Match object; span=(0, 1), match='_'>
2.11 \W
非数字、字母和下划线,等价于[^\w]
>>> re.match(r"\W","*12we")
<_sre.SRE_Match object; span=(0, 1), match='*'
>>> re.search(r"\W+","23#@")
<_sre.SRE_Match object; span=(2, 4), match='#@'>
2.12 *(星号)
匹配一个字符0次或多次,需要注意的是正则默认的贪婪性,会在满足匹配的条件下继续贪婪更多的匹配
>>> re.search(r"\d*","asd")
<_sre.SRE_Match object; span=(0, 0), match=''> #匹配0次,返回为空
>>> re.search(r"\d*","123")
<_sre.SRE_Match object; span=(0, 3), match='123'>
>>> re.search(r"\d*?","123")
<_sre.SRE_Match object; span=(0, 0), match=''> #用问号抑制贪婪性,*最小匹配0次
2.13 +(加号)
匹配一个字符1次或多次,注意正则的贪婪性
>>> re.match(r"\d+","123d")
<_sre.SRE_Match object; span=(0, 3), match='123'>
>>> re.match(r"\d+?","123d")
<_sre.SRE_Match object; span=(0, 1), match='1'> #用问号抑制贪婪性,+最小匹配1次
2.14 ?(问号)
匹配一个字符0次或1次,用在数量词(*/+/{m}/{m,n})的后面,表示抑制贪婪性
>>> re.match(r"\d?","as23")
<_sre.SRE_Match object; span=(0, 0), match=''>
>>> re.match(r"\d?","23abc")
<_sre.SRE_Match object; span=(0, 1), match='2'>
2.15 {}(大括号)
{m}:匹配前一个字符m次
{m,n}:匹配前一个字符m到n次;匹配前一个字符最少m次,最多n次
>>> re.search(r"a{3}","aabb")
>>> re.search(r"a{3}","aaabb")
<_sre.SRE_Match object; span=(0, 3), match='aaa'>
>>> re.search(r"a{2,4}","aabb")
<_sre.SRE_Match object; span=(0, 2), match='aa'>
>>> re.search(r"a{2,4}","aaabb")
<_sre.SRE_Match object; span=(0, 3), match='aaa'>
>>> re.search(r"a{2,4}","aaaabb")
<_sre.SRE_Match object; span=(0, 4), match='aaaa'>
>>> re.search(r"a{2,4}","aaaaabb")
<_sre.SRE_Match object; span=(0, 4), match='aaaa'>
2.16 ^(脱字符)
匹配字符串开头,如果是多行则匹配每一行的开头。在[...]中,^表示否定,如非字母[^a-zA-Z],非数字[^0-9]
>>> re.search(r"^abc","abc12")
<_sre.SRE_Match object; span=(0, 3), match='abc'>
>>> re.search(r"^abc","abc12\nabc")
<_sre.SRE_Match object; span=(0, 3), match='abc'>
2.17 $(美元符)
匹配字符串或一行的结尾,如果是多行则匹配每一行的结尾
>>> re.search(r"\d+$","asdf234")
<_sre.SRE_Match object; span=(4, 7), match='234'>
>>> re.search(r"^123$","123") #精确匹配
<_sre.SRE_Match object; span=(0, 3), match='123'>
2.18 \A
非多行匹配的时候等价于^,多行匹配的是\A将整个字符串看作一个整体匹配,而^能够匹配每一行的开头
>>> re.findall(r"\A\d","12\n34\n565\n")
['1']
>>> re.findall(r"\A\d","12\n34\n565\n",re.M)
['1']
>>> re.findall(r"\A\d+","12\n34\n565\n",re.M)
['12']
>>> re.findall(r"^\d+","12\n34\n565\n",re.M)
['12', '34', '565']
2.19 \Z
非多行匹配时等价于$,多行匹配的是\Z将整个字符串看作一个整体匹配,而$能够匹配每一行的结尾
>>> re.findall(r"\d+$","abc43")
['43']
>>> re.findall(r"\d+\Z","abc43")
['43']
>>> re.findall(r"\d+\Z","abc43\new22\n5")
['5']
>>> re.findall(r"\d+\Z","abc43\new22\n5",re.M)
['5']
>>> re.findall(r"\d+$","abc43\new22\n5",re.M)
['43', '22', '5']
>>> re.findall(r"\d+$","abc43\new22\n5")
['5']
3.正则表达式
re.match(pattern, string, flags=0)方法
用于从字符串的开始处进行匹配,如果在起始位置匹配成功,则返回Match对象,否则返回None
参数说明:
pattern:匹配的正则表达式
string:被匹配的字符串
flags:标志位,用于控制正则表达式的匹配方式,如是否区分大小写,是否匹配多行等
>>> import re
>>> re.match(r"a","abc")
<_sre.SRE_Match object; span=(0, 1), match='a'>
#返回匹配结果对象,span表示是匹配的开始位置和结束位置,开区间
>>> print (re.match(r"a","bc"))
None
re.search(pattern, string, flags=0)方法
用于在整个字符串中搜索第一个匹配的值,如果匹配成功,则返回Match对象,否则返回None
参数说明:
pattern:匹配的正则表达式
string:被匹配的字符串
flags:标志位,用于控制正则表达式的匹配方式,如是否区分大小写,是否匹配多行等
>>> re.search(r"ac","vcac")
<_sre.SRE_Match object; span=(2, 4), match='ac'>
>>> print (re.search(r"ab","vcac"))
None
re.findall(pattern, string, flags=0)方法
用于在整个字符串中查找字符串中所有能匹配的字符串,如果匹配成功,则将结果存于列表中,然后返回该列表;否则返回空列表。特殊的地方在于返回的列表中的内容,取决于正则表达式中圆括号的出现情况,也就是分组情况。
参数说明:
pattern:匹配的正则表达式
string:被匹配的字符串
flags:标志位,用于控制正则表达式的匹配方式。如是否区分大小写、是否多行匹配等
1.正则表达式中没有圆括号时,返回列表中的元素由所有成功匹配的子串组成;
>>> import re
>>> re.findall(r"\d+","12ab34cd56ef")
['12', '34', '56']
>>> re.findall(r"\d+","abcdef")
[]
>>> res = re.findall(r'\w*oo\w*', 'woo this foo is too')
>>> print(res)
['woo', 'foo', 'too']
2.当正则表达式中含有多个圆括号()时,返回列表中的元素由所有满足匹配的内容组成,但
是每个元素都是由表达式中所有圆括号匹配的内容组成的元组。而且元组中元素个数与括 号对数相同,并且字符串排放顺序跟括号出现的顺序一致(一般看左括号‘ (’就行),
字符串内容与每个括号内的正则表达式相对应
>>> re.findall(r"(a)b(c)","abcabcabc")
[('a', 'c'), ('a', 'c'), ('a', 'c')]
>>> add = 'https://www.net.com.edu//action=?asdfsd and other https://www.baidu.com//a=b'
>>> res = re.findall(r'((w{3}\.)(\w+\.)+(com|edu|cn|net))',add)
>>> print(res)
[('www.net.com.edu', 'www.', 'com.', 'edu'), ('www.baidu.com', 'www.', 'baidu.', 'com')]
3.当正则表达式中只带有一个圆括号时,返回的列表的元素由所有能成功匹配表达式中圆括
号匹配的内容组成,并且该列表中的元素都是字符串,它的内容与括号中的正则表达式相对
应。(注意:列表中的字符串只是圆括号中的内容,不是整个正则表达式所匹配的内容。)
>>> re.findall(r"(a)bc","abcabcabc")
['a', 'a', 'a']
>>> res = re.findall(r'.*?(\d+).*?','adsd12343.jl34d5645fd789')
>>> print(res)
['12343', '34', '5645', '789']
re.finditer(pattern, string, flags=0)方法
和findall函数一样,匹配字符串中所有满足的子串,只是返回的是迭代器,而不是存有所有结果的list,这个迭代器里面存的是每一个结果的匹配对象,这样可以节省空间,一般用在需要匹配大量的结果情况下
参数说明:
pattern:匹配的正则表达式
string:被匹配的字符串
flags:标志位,用于控制正则表达式的匹配方式,如是否区分大小写,是否匹配多行等
#匹配字符串中所有连续字母组成的子串
#encoding=utf-8
import re
for i in re.finditer(r'[A-Za-z]+','one12two34three56four'):
print(i.group())
re.split(pattern, string, maxsplit=0, flags=0)方法
分割字符串,将字符串用给定的正则表达式匹配的字符串进行分割,分割后返回结果list
参数说明:
pattern:匹配的正则表达式
string:被分割的字符串
maxsplit:最大的分割次数
flags:标志位,用于控制正则表达式的匹配方式。如是否区分大小写、是否多行匹配等
>>> re.split(r"\d+","one1two2three3four4") #不指定分割次数
['one', 'two', 'three', 'four', '']
>>> re.split(r"\d+","one1two2three3four4",2) #指定分割次数
['one', 'two', 'three3four4']
>>> s = "a 2 b 2 c 5 d" #切割出字母
>>> re.split(r"\s+\d\s+",s)
['a', 'b', 'c', 'd']
re.sub(pattern, repl, string, count=0, flags=0)方法
使用repl替换string中每一个匹配的子串后返回替换后的字符串。
参数说明:
pattern:匹配的正则表达式
repl:用于替换的字符串
string:要被替换的字符串
count:替换的次数,如果为0表示替换所有匹配到的字串,如果是1表示替换1次等,该参数必须是非负整数,默认为0。
flags:标志位,用于控制正则表达式的匹配方式。如是否区分大小写、是否多行匹配等。
>>> tel = '13549876489' #将手机号的后四位替换为0
>>> re.sub(r"\d{4}$","0000",tel)
'13549870000'
>>> s = 'num = 0 #a number' #将代码后面的注释去掉
>>> re.sub(r"#.*$","",s)
'num = 0 '
使用mul方法作为repl参数,将匹配的每个数字作为参数传入到mul函数,处理后将返回结果替换为相应字符串
#encoding:utf-8
import re
content="10 20 30 40 50"
def mul(m):
num=int(m.group())
return str(num*2)
result=re.sub("\d+",mul,content)
print (result)
re.subn(pattern, repl, string, count=0, flags=0)方法
与sub函数用法类似,只是有一个额外的特征,结果返回一个tuple,tuple第一个元素是替换后的新字符串,第二个元素是替换的次数
>>> re.subn(r"\d+","","12a34b56c")
('abc', 3)
4.正则修饰符
常用修饰符 | 描述 |
re.I | 全写(re.IGNORECASE),表示匹配时忽略大小写 |
re.M | 全写(re.MULTILINE),多行匹配,影响 ^ 和 $的行 |
re.S | 全写(re.DOTALL),使点(.)匹配包括换行在内的所有字 |
re.X | 全写(VERBOSE),忽略模式字符串中未转义的空格和注释 |
re.I实例:
代码示例:默认情况下使用精确匹配文字的大小写
>>> result=re.match(r"[A-Z]+","asdf12")
>>> print (result)
None
代码示例:使用re.I忽略大小写模式匹配字符串
>>> result=re.match(r"[A-Z]+","asdf12",re.I)
>>> print (result)
<_sre.SRE_Match object; span=(0, 4), match='asdf'>
>>> print (result.group())
asdf
re.M实例:
代码示例:未使用re.M,会匹配多 行文字的最后一行的结尾
>>> content="""I am a boy\nyou r a beautiful girl\nright"""
>>> re.findall(r"\w+$",content)
['right']
代码示例:使用re.M,会匹配多行文字的每行结尾, 也就是屏蔽多行匹配
>>> re.findall(r"\w+$",content,re.M)
['boy', 'girl', 'right']
re.S实例:
代码示例:使点(.)匹配包括换行在内的所有字符
>>> s="I am a boy\nyour a girl"
>>> re.search(r".*",s).group()
'I am a boy'
>>> re.search(r".*",s,re.S).group()
'I am a boy\nyour a girl'
re.X实例:
代码示例:
import re
pattern=re.compile(r"""\d+ #匹配至少1个连续的数字
\. #匹配点(.)
\d* #匹配数字至少0个""",re.X)
print (pattern.search("test12.58 2.0").group())
#两个正则表达式是等价的
pattern1=re.compile(r"\d+\.\d*")
print (pattern1.search("test12.58 2.0").group())
结合使用
import re
p=re.compile(r"^.*[a-z]+$",re.I|re.S)
targetString='''I am a Boy
you are a Beautiful Girl
Right'''
result=p.search(targetString)
if result:
print (result.group())
else:
print ("no string found!")