常用特殊字符匹配内容
字符匹配:
正则特殊字符 | 匹配内容 |
---|---|
. | 匹配除换行符(\n)以外的单个任意字符 |
\w | 匹配单个字母、数字、汉字或下划线 |
\s | 匹配单个任意的空白符 |
\d | 匹配单个数字 |
\b | 匹配单词的开始或结束 |
^ | 匹配整个字符串的开头 |
$ | 匹配整个字符串的结尾 |
次数匹配:
正则特殊字符 | 匹配内容 |
---|---|
* | 重复前一个字符 0 - n 次 |
+ | 重复前一个字符 1 - n 次 |
? | 重复前一个字符 0 - 1 次 |
{n} | 重复前一个字符 n 次 a{2} 匹配 aa |
{n,} | 重复前一个字符 n 次或 n 次以上 a{2,} 匹配 aa 或aaa 以上 |
{n, m} | 重复前一个字符 n 到 m 次之间的任意一个都可以 |
Python 中使用正则的方法
match
只在整个字符串的起始位置进行匹配
示例字符串
string = "isinstance yangge enumerate www.qfedu.com 1997"
示例演示:
import re
In [4]: r = re.match("is\w+", string)
In [8]: r.group() # 获取匹配成功的结果
Out[8]: 'isinstance'
search
从整个字符串的开头找到最后,当第一个匹配成功后,就不再继续匹配。
In [9]: r = re.search("a\w+", string)
In [10]: r.group()
Out[10]: 'ance'
findall
搜索整个字符串,找到所有匹配成功的字符串,比把这些字符串放在一个列表中返回。
In [16]: r = re.findall("a\w+", string)
In [17]: r
Out[17]: ['ance', 'angge', 'ate']
sub
把匹配成功的字符串,进行替换。
# 语法:
"""
("a\w+", "100", string, 2)
匹配规则,替换成的新内容, 被搜索的对象, 有相同的话替换的次数
"""
In [24]: r = re.sub("a\w+", "100", string, 2)
In [25]: r
Out[25]: 'isinst100 y100 enumer100 www.qfedu.com 1997'
# 模式不匹配时,返回原来的值
split
以匹配到的字符进行分割,返回分割后的列表
In [26]: string
Out[26]: 'isinstance yangge enumerate www.qfedu.com 1997'
In [27]: r = re.split("a", string, 1)
使用多个界定符分割字符串
>>> line = 'asdf fjdk; afed, fjek,asdf, foo'
>>> import re
>>> re.split(r'[;,\s]\s*', line)
['asdf', 'fjdk', 'afed', 'fjek', 'asdf', 'foo']
正则分组
==从已经成功匹配的内容中,再去把想要的取出来==
# match
In [64]: string
Out[64]: 'isinstance yangge enumerate www.qfedu.com 1997'
In [65]: r = re.match("is(\w+)", string)
In [66]: r.group()
Out[66]: 'isinstance'
In [67]: r.groups()
Out[67]: ('instance',)
In [68]: r = re.match("is(in)(\w+)", string))
In [69]: r.groups()
Out[69]: ('in', 'stance')
# search
# 命名分组
In [87]: r = re.search("is\w+\s(?Py\w+e)", string)
In [88]: r.group()
Out[88]: 'isinstance yangge'
In [89]: r.groups()
Out[89]: ('yangge',)
In [90]: r.groupdict()
Out[90]: {'name': 'yangge'}
# findall
In [98]: string
Out[98]: 'isinstance all yangge any enumerate www.qfedu.com 1997'
In [99]: r = re.findall("a(?P\w+)", string)
In [100]: r
Out[100]: ['nce', 'll', 'ngge', 'ny', 'te']
In [101]: r = re.findall("a(\w+)", string)
In [102]: r
Out[102]: ['nce', 'll', 'ngge', 'ny', 'te']
# split
In [113]: string
Out[113]: 'isinstance all yangge any enumerate www.qfedu.com 1997'
In [114]: r = re.split("(any)", string)
In [115]: r
Out[115]: ['isinstance all yangge ', 'any', ' enumerate www.qfedu.com 1997']
In [116]: r = re.split("(a(ny))", string)
In [117]: r
Out[117]:
['isinstance all yangge ',
'any',
'ny',
' enumerate www.qfedu.com 1997']
In [118]: tag = 'value="1997/07/01"'
In [119]: s = re.sub(r'(value="\d{4})/(\d{2})/(\d{2}")', r'\1-\2-\3', tag)
In [120]: s
Out [120]: value="1997-07-01"
编译正则
对于程序频繁使用的表达式,编译这些表达式会更有效。
compile 函数用于编译正则表达式,返回的是一个正则表达式( Pattern )对象,利用这个对象的相关方法再去匹配字符串。
好处:
re 模块会维护已编译表达式的一个缓存。
不过,这个缓存的大小是有限的,直接使用已编译的表达式可以避免缓存查找开销。
使用已编译表达式的另一个好处是,通过在加载模块时预编译所有表达式,可以把编译工作转到应用 一开始时,而不是当程序响应一个用户动作时才进行编译。
In [130]: regexes = re.compile("y\w+")
In [131]: r = regexes.search(string)
In [132]: r.group()
Out[132]: 'yangge'
常用正则
# IP:
r'^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$'
# 手机号:
r'^1[3|4|5|8][0-9]\d{8}$'
# 邮箱:
[email protected]
[email protected]
r'[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(.[a-zA-Z0-9_-]+)+'
强调知识点
# 匹配所有包含小数在内的数字
print(re.findall('\d+\.?\d*',"asdfasdf123as1.13dfa12adsf1asdf3")) #['123', '1.13', '12', '1', '3']
#.*默认为贪婪匹配
print(re.findall('a.*b','a1b22222222b')) #['a1b22222222b']
#.*?为非贪婪匹配:推荐使用
print(re.findall('a.*?b','a1b22222222b')) #['a1b']
元字符
# \b 表示匹配单词边界,详见后面的速查表
In [17]: re.search('hello\b', 'hello world')
In [18]: re.search('hello\\b', 'hello world')
Out[18]: <_sre.SRE_Match object; span=(0, 5), match='hello'>
Python 自己也有转义
使用 r
禁止 Python
转义
In [19]: re.search(r'hello\b', 'hello world')
Out[19]: <_sre.SRE_Match object; span=(0, 5), match='hello'>
扩展知识点
最后一个参数 flag
可选值有:
re.I # 忽略大小写
示例:
In [186]: s1 = string.capitalize()
In [187]: s1
Out[187]: 'Isinstance all yangge any enumerate www.qfedu.com 1997'
In [192]: r = re.search('is',s, re.I)
Out[192]: <_sre.SRE_Match object; span=(0, 2), match='Is'>
正则模式速查表
模式 | 描述 | |
---|---|---|
^ | 匹配字符串的开头 | |
$ | 匹配字符串的末尾。 | |
. | 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。 | |
[...] | 用来表示一组字符,单独列出:[amk] 匹配 'a','m'或'k' | |
[^...] | 不在[]中的字符:[^abc] 匹配除了a,b,c之外的字符。 | |
re* | 匹配0个或多个的表达式。 | |
re+ | 匹配1个或多个的表达式。 | |
re? | 匹配0个或1个由前面的正则表达式定义的片段,非贪婪方式 | |
re{ n} | 匹配n个前面表达式。。例如,"o{2}"不能匹配"Bob"中的"o",但是能匹配"food"中的两个o。 | |
re{n,} | 精确匹配n个前面表达式。例如,"o{2,}"不能匹配"Bob"中的"o",但能匹配"foooood"中的所有o。"o{1,}"等价于"o+"。"o{0,}"则等价于"o*"。 | |
re{n,m} | 匹配 n 到 m 次由前面的正则表达式定义的片段,贪婪方式 | |
a | b | 匹配a或b |
(re) | 匹配括号内的表达式,也表示一个组 | |
(?imx) | 正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域。 | |
(?-imx) | 正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。 | |
(?: re) | 类似 (...), 但是不表示一个组 | |
(?imx: re) | 在括号中使用i, m, 或 x 可选标志 | |
(?-imx: re) | 在括号中不使用i, m, 或 x 可选标志 | |
(?#...) | 注释. | |
(?= re) | 前向肯定界定符。如果所含正则表达式,以 ... 表示,在当前位置成功匹配时成功,否则失败。但一旦所含表达式已经尝试,匹配引擎根本没有提高;模式的剩余部分还要尝试界定符的右边。 | |
(?! re) | 前向否定界定符。与肯定界定符相反;当所含表达式不能在字符串当前位置匹配时成功 | |
(?> re) | 匹配的独立模式,省去回溯。 | |
\w | 匹配字母数字及下划线 | |
\W | 匹配非字母数字及下划线 | |
\s | 匹配任意空白字符,等价于 [\t\n\r\f]. | |
\S | 匹配任意非空字符 | |
\d | 匹配任意数字,等价于 [0-9]. | |
\D | 匹配任意非数字 | |
\A | 匹配字符串开始 | |
\Z | 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。 | |
\z | 匹配字符串结束 | |
\G | 匹配最后匹配完成的位置。 | |
\b | 匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。 | |
\B | 匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。 | |
\n, \t, 等. | 匹配一个换行符。匹配一个制表符。等 | |
\1...\9 | 匹配第n个分组的内容。 | |
\10 | 匹配第n个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式。 |