正则表达式也叫做匹配模式(Pattern),它由一组具有特定含义的字符串组成,通常用于匹配和替换文本。
正则表达式(英语:Regular Expression、regex 或 regexp,缩写为 RE),也译为正规表示法、常规表示法,在计算机科学中,是指一个用来描述或者匹配一系列符合某个句 法规则的字符串的单个字符串。
>>> dir(re)
['A', 'ASCII', 'DEBUG', 'DOTALL', 'I', 'IGNORECASE', 'L', 'LOCALE',
'M', 'MULTILINE', 'Match', 'Pattern', 'RegexFlag', 'S', 'Scanner',
'T', 'TEMPLATE', 'U', 'UNICODE', 'VERBOSE', 'X', '_MAXCACHE',
'__all__', '__builtins__', '__cached__', '__doc__', '__file__',
'__loader__', '__name__', '__package__', '__spec__',
'__version__', '_cache', '_compile', '_compile_repl', '_expand',
'_locale', '_pickle', '_special_chars_map', '_subx', 'compile',
'copyreg', 'enum', 'error', 'escape', 'findall', 'finditer',
'fullmatch', 'functools', 'match', 'purge', 'search', 'split',
'sre_compile', 'sre_parse', 'sub', 'subn', 'template']
re.compile(string[,flag])
在参数中我们传入了原生字符串对象,通过compile方法编译生成一个pattern对象,然后我们利用这个对象来进行进一步的匹配。
>>> str = "You Are Really Beautifull"
>>> p = re.compile("you",re.I)
>>> p.match(str)
<re.Match object; span=(0, 3), match='You'>
参数flag是匹配模式:
re.findall()
匹配所有的对象,返回一个列表
>>> re.findall(r"\d+","1,当前浏览量是8848次,回帖人数是520人")
['1', '8848', '520']
re.finditer()
返回一个迭代器 iterator,这个 iterator yield match objects.返回顺序、内容和 re.findall() 相同
>>> re.finditer('[a-n]', 'liujianhong')
<callable_iterator at 0x7f6c58629e10>
>>> q = re.finditer('[a-n]', 'liujianhong')
>>> next(q)
<re.Match object; span=(0, 1), match='l'>
>>> next(q)
<re.Match object; span=(1, 2), match='i'>
>>> next(q)
<re.Match object; span=(3, 4), match='j'>
re.match(pattern, string[, flags])
这个方法将会从string(我们要匹配的字符串)的开头开始,尝试匹配pattern,一直向后匹配,如果遇到无法匹配的字符,立即返回None,如果匹配未结束已经到达string的末尾,也会返回None。两个结果均表示匹配失败,否则匹配pattern成功,同时匹配终止,不再对string向后匹配。
>>> s
'我今年16岁了,我错了,我今年已经17岁了'
>>> re.match(r".*\d+.*",s)
<re.Match object; span=(0, 21), match='我今年16岁了,我错了,我今年已经17岁了'>
>>> res = re.match(r".*\d+.*",s)
>>> res.group()
'我今年16岁了,我错了,我今年已经17岁了'
re.search(pattern, string[, flags])
执行正则表达式搜索并且在搜索结束后返回所匹配到的串,只返回第一次匹配到的结果
>>> import re
>>> res = re.search(r"\d+","当前浏览量是 8808 次")
>>> res.group()
'8808'
re.split(pattern, string[, maxsplit])
按照能够匹配的子串将string分割后返回列表。maxsplit用于指定最大分割次数,不指定将全部分割。
>>> path = "http://www.baidu.com"
>>> re.split("\.",path)
['http://www', 'baidu', 'com']
re.sub(pattern, repl, string[, count])
使用repl替换string中每一个匹配的子串后返回替换后的字符串。
当需要同时返回替换次数是,可以使用:
re.subn(pattern, repl, string[, count])
>>> re.sub("\d+","1024","访问量位8808次")
'访问量位1024次'
代码 | 说明 |
---|---|
\d | # 匹配一个数字 |
. | # 匹配任意符号,除换行符‘\n’外,\默认添加 |
\w | # 匹配所有的有效符号(大小写字母,数字,下划线,国家语言符号) |
\s | # 匹配任意空白符(如空格符号、‘’\t’) |
^ | # 匹配以什么(后面紧跟的字符)开头(此处开头为字符串的开头),默认匹配到结尾 |
¥ | # 匹配以什么结尾与^对立, |
[ ] | # 例举 # [0123456789] <=> “”\d” #[a-z] 表实小写的a~z的所有字母,即可用“-”来表示范围,[A-Za-z0-9_] <=> 有效符号 # 所有中文:[\u4e00-\u9fa5] |
代码 | 说明 |
---|---|
\D | # 匹配非数字符号 |
\W | # 匹配非有效符号,即特殊符号 |
\S | # 匹配非空白符 |
[^] | # 表示跟列举相反,即不能匹配所列举的符号 |
如果你想查找元字符本身的话,比如你查找’.‘,或者‘*’,就出现了问题:你没法指定它们,因 为它们会被解释成其它的意思。这时你就必须使用\来取消这些字符的特殊意义。因此,你应该使用.和*。当然,要查找\本身,你也得用\.
re.match("c:\\\\","c:\\a\\b")
#这里需要四个反斜杠,因为字符串需要转义,正则也要转义,当然也可以用下列的方式
re.match(r"c:\\","c:\\a\\b") #r表示匹配的字符不进行转义
#这样也可以达到相同的效果
这里建议以后在写正则的时候,一定要在正则表达式前面加上r,避免出现上述的情况
代码 | 说明 |
---|---|
* | # 表示匹配任意位(>= 0) |
+ | # 表示至少一位(>= 1) |
? | # 表示0位或者1位,即要么没有,要么有,有的话不能超过1位 |
{n} | # 表示有n位 |
{n,m} | # 表示n-m这个范围 |
在正则表达式中,使用圆括号()将正则中包裹起来,会形成正则匹配后得二次筛选
>>> re.match("\d+(183|192|168)\s","452183 ").group(1)
'183'
>>> re.match("\d+(183|192|168)\.(li|wang|liu)","452168.wang").group(1)
'168'
>>> re.match("\d+(183|192|168)\.(li|wang|liu)","452168.wang").group(2)
'wang'
r"?.+?>" # 匹配标签
r"<(\w+)>.*\1>" # 匹配开始与结尾标签,\1被称为后向引用(即用于重复搜索前面莫格分组匹配得文本)
在 Python 中正则默认是贪婪模式(个别语言中也可能是非贪婪模式),贪婪模式就是总会尝试匹配更多的字符。
非贪婪模式则反之,总是尝试匹配尽可能少的字符。
在*、?、+、{m,n}后面加上?,可以将贪婪模式变成非贪婪模式。
代码 | 说明 |
---|---|
*? | 重复任意次,但尽可能少得重复 |
+? | 重复1次或更多次,但尽可能少得重复 |
?? | 重复0次或1次,但尽可能少得重复 |
{n,m}? | 重复n到m次,但尽可能少得重复 |
{n,}? | 重复n次以上,但尽可能少得重复 |