[RegEx] - 正则表达式
摘要:关于正则表示的使用,但我还是喜欢直接查正则表达式手册
正则表达式基本规则
特殊字符
[]表示匹配范围(在方括号中填写匹配字符),下面列举了一些常用特殊字符。
需要注意的是,能被Python识别的特殊字符需要添加转义字符。例如:匹配(需要这样写(转义):
[\(]
^、$以及\b的使用示例
s = 'HELLO World'
print re.findall(r"^hello", s, re.I)
print re.findall(r"world$", s, re.I)
print re.findall(r"\b\w+\b",s)
输出:
['HELLO']
['World']
['HELLO', 'World']
^hello表示以hello开头的字符子串,参数re.I表示忽略大小写;
world$表示以world结尾的字符子串,参数re.I表示忽略大小写;
\bw+\b表示[匹配单词的开始]+[匹配多个字母]+[匹配单词的结束]
限定字符
可以理解为,*表示可以匹配任意多次,+表示至少匹配一次,?表示至多一次。
e.g.匹配电话号码
例如我需要匹配如下格式的电话号码
0371-1234567、010-12345678、(0371)1234567
正则表达式可以这样写:
[\(]?\d{3}[\)-]?\d{8}|[\(]?\d{4}[\)-]?\d{7}
解释:
[\(]?表示匹配至多一次的( \d{3}表示匹配三个数字字符,相当于\d\d\d [\)-]?表示匹配)或-两个字符中的一个
\d{8}表示匹配八个数字字符,相当于\d\d\d\d\d\d\d\d |用于分隔两个正则表达式,意为或
你也可以进入在线正则表达式测试进行练习。
分组嵌套
使用()对正则表达式进行嵌套。匹配如下字符串123123,这是由123重复两次构成的字符,构造正则表达式 (\d{3}){2}或(\d\d\d){2},匹配返回['123']
。然而表达式(\d\d\d)(\d\d\d),匹配返回[('123', '123')]。
正则表达式的每个分组会自动拥有一个组号,从左往右第1个出现的圆括号为第1个分组,表示为“\1”;第2个出现的圆括号为第2个分组,表示为“\2”,依次类推。
例如匹配字符串abcabcabc,构造正则表达式(\w{3})\1,则匹配到的字符为abcabc。相当于(\w\w\w)(\w\w\w)。
分组除了自动拥有一个组号还可以自行重命名,例如匹配字符串abcabc查找其中重复的子串abc,可以构造正则表达式
(?P<repeat>a\wc)(?P=repeat)
在Python中你可以这样运行:
import re
s = 'abcabc'
print re.findall(r"(?P<repeat>a\wc)(?P=repeat)", s)
输出:
['abc']
限定符的组合
默认情况下,正则表达式匹配最长字符串。例如匹配字符串abcabc,构造正则表达式a.*c(ab之间匹配任意多次的字符),则返回的是abcabc。
若需要最短匹配可以这样写:a.*?c(可以匹配不到也可以匹配到多个)、a.+?c(至少匹配到一个)、a.??c(至多匹配一个?)
使用re模块处理正则表达式
re模块下的常用函数
findall(pattern, string ,flag=0)
pattern表示正则表达式,string表示待匹配字符串,flag为可选参数,规则选项可以参考下表
例如,re.I表示忽略大小写。
sub(pattern, repl, string, count = 0)
该函数用于替换匹配到的字符串,repl表示用于替换的字符串,count为可选参数默认为0,表示替换所有匹配到的子串,若count大于0则替换匹配到的前count个子串。
import re
a='123123'
re.sub(r"(\d{3})", 'abc', a, count = 1)
输出:
'abc123'
subn(pattern, repl, string, count = 0)
功能和sub相同,不同的输出不一样,该函数返回的是二元组,第一个元素表示替换结果,第二个元素表示替换次数。
re.subn(r"(\d{3})",'abc',a,count = 2)
输出
('abcabc', 2)
match(pattern, string, flag = 0)
必须从string头部(string[0])开始匹配,只返回第一次匹配成功的Match对象,如果string[0]不符合要求则匹配失败返回None。
search(pattern, string, flag = 0)
和match不同的是match必须要从string[0]开始匹配。
a='123123'
m=re.match(r"(\d{3})",a)
print m.group()
利用group获得所有匹配的分组字符串,0号组用于存储匹配整个正则表达式的结果。group(1)用于存储第一个分组表达式匹配结果,依次类推。若分组重命名了使用group(name)获取。
compile(pattern, flag = 0)
正则表达式的解析非常费时。如果多次使用findall()的方式匹配字符串,搜索效率可能比较低。如果多次使用同一规则匹配字符串,可以使用compile()进行预编译,compile函数返回1个pattern对象。该对象拥有一系列方法用于查找、替换或扩展字符串,从而提高字符串的匹配速度。下表列出了pattern对象的属性和方法。
import re
s = "1abc23def45"
p = re.compile(r"\d+")
print p.findall(s)
print p.pattern
d+如果使用d*或者d?都会因为扫描字符串时因未匹配到字符而返回空元素。
例如前者会返回 :
['1', '', '', '', '23', '', '', '', '45', '']
后者因为至多匹配一次返回:
['1', '', '', '', '2', '3', '', '', '', '4', '5', '']
函数compile()通常与match()、search()、group()一起使用,对含有分组的正则表达式进行解析。正则表达式的分组从左往右开始计数,第1个出现的圆括号标记为第1组,依次类推。此外还有0号组,0号组用于存储匹配整个正则表达式的结果。match()和search()将返回1个match对象,match对象提供了一系列的方法和属性来管理匹配的结果。下表出了match对象的方法和属性。
参考书籍
参考
摘抄自:RegEx - 正则表达式 - 知乎,感谢作者。
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。