\’.\’ 匹配所有字符串,除\n以外
‘-’ 表示范围[0-9]
\’*\’ 匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 \*。
\’+\’ 匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 \+
\’^\’ 匹配字符串开头
‘$’ 匹配字符串结尾 re
\’\\’ 转义字符, 使后一个字符改变原来的意思,如果字符串中有字符*需要匹配,可以\*或者字符集[*] re.findall(r\’3\*\’,\’3*ds\’)结[\’3*\’]
\’*\’ 匹配前面的字符0次或多次 re.findall(“ab*”,”cabc3abcbbac”)结果:[\’ab\’, \’ab\’, \’a\’]
‘?’ 匹配前一个字符串0次或1次 re.findall(\’ab?\’,\’abcabcabcadf\’)结果[\’ab\’, \’ab\’, \’ab\’, \’a\’]
\'{m}\’ 匹配前一个字符m次 re.findall(\’cb{1}\’,\’bchbchcbfbcbb\’)结果[\’cb\’, \’cb\’]
\'{n,m}\’ 匹配前一个字符n到m次 re.findall(\’cb{2,3}\’,\’bchbchcbfbcbb\’)结果[\’cbb\’]
\’\d\’ 匹配数字,等于[0-9] re.findall(\’\d\’,\’电话:10086\’)结果[\’1\’, \’0\’, \’0\’, \’8\’, \’6\’]
\’\D\’ 匹配非数字,等于[^0-9] re.findall(\’\D\’,\’电话:10086\’)结果[\’电\’, \’话\’, \’:\’]
\’\w\’ 匹配字母和数字,等于[A-Za-z0-9] re.findall(\’\w\’,\’alex123,./;;;\’)结果[\’a\’, \’l\’, \’e\’, \’x\’, \’1\’, \’2\’, \’3\’]
\’\W\’ 匹配非英文字母和数字,等于[^A-Za-z0-9] re.findall(\’\W\’,\’alex123,./;;;\’)结果[\’,\’, \’.\’, \’/\’, \’;\’, \’;\’, \’;\’]
\’\s\’ 匹配空白字符 re.findall(\’\s\’,\’3*ds \t\n\’)结果[\’ \’, \’\t\’, \’\n\’]
\’\S\’ 匹配非空白字符 re.findall(\’\s\’,\’3*ds \t\n\’)结果[\’3\’, \’*\’, \’d\’, \’s\’]
\’\A\’ 匹配字符串开头
\’\Z\’ 匹配字符串结尾
\’\b\’ 匹配单词的词首和词尾,单词被定义为一个字母数字序列,因此词尾是用空白符或非字母数字符来表示的
\’\B\’ 与\b相反,只在当前位置不在单词边界时匹配
\'(?P<name>…)\’ 分组,除了原有编号外在指定一个额外的别名 re.search(“(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{8})”,”371481199306143242″).groupdict(“city”) 结果{\’province\’: \’3714\’, \’city\’: \’81\’, \’birthday\’: \’19930614\’}
[] 是定义匹配的字符范围。比如 [a-zA-Z0-9] 表示相应位置的字符要匹配英文字符和数字。[\s*]表示空格或者*号。
二.常用的re函数:
方法/属性 |
作用 |
re.match(pattern, string, flags=0) |
从字符串的起始位置匹配,如果起始位置匹配不成功的话,match()就返回none |
re.search(pattern, string, flags=0) |
扫描整个字符串并返回第一个成功的匹配 |
re.findall(pattern, string, flags=0) |
找到RE匹配的所有字符串,并把他们作为一个列表返回 |
re.finditer(pattern, string, flags=0) |
找到RE匹配的所有字符串,并把他们作为一个迭代器返回 |
re.sub(pattern, repl, string, count=0, flags=0) |
替换匹配到的字符串 |
函数参数说明:
pattern:匹配的正则表达式。
string:要匹配的字符串。
flags:标记为,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
repl:替换的字符串,也可作为一个函数。
count:模式匹配后替换的最大次数,默认0表示替换所有匹配。
例子1
#!/usr/bin/python3
import re
#替换
phone = \'18898537584 #这是我的电话号码\'
print(\'我的电话号码:\',re.sub(\'#.*\',\'\',phone)) #去掉注释
print(re.sub(\'\D\',\'\',phone))
#search
ip_addr = re.search(\'(\d{3}\.){1,3}\d{1,3}\.\d{1,3}\',os.popen(\'ifconfig\').read())
print(ip_addr)
#match
>>> a = re.match(\'\d+\',\'2ewrer666dad3123df45\')
>>> print(a.group())
2
获取匹配的函数:
方法/属性 |
作用 |
group(num=0) |
匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。 |
groups() |
返回包含所有小组字符串的元组,从1到所含的小组 |
groupdict() |
返回以有别名的组的别名为键、以该组截获的子串为值的字典 |
start() |
返回匹配开始的位置 |
end() |
返回匹配结束的位置 |
span() |
返回一个元组包含匹配(开始,结束)的位置 |
三.原生字符串,字符,分组
1.原生字符串
每一次在匹配规则前面加了一个r,表示不转义,使用原生字符串,没用原始字符串,也没出现什么问题。那是因为ASCII 里没有对应的特殊字符,所以正则表达式编译器能够知道你指的是一个十进制数字。但是我们写代码本着严谨简单的原理,最好是都写成原生字符串的格式。
import re
# “\b”在ASCII 字符中代表退格键,\b”在正则表达式中代表“匹配一个单词边界”
print(re.findall("\bblow", "jason blow cat")) # 这里\b代表退格键,所以没有匹配到
print(re.findall("\\bblow", "jason blow cat")) # 用\转义后这里就匹配到了 [\'blow\']
print(re.findall(r"\bblow", "jason blow cat")) # 用原生字符串后就不需要转义了 [\'blow\']
#执行结果:
[]
[\'blow\']
[\'blow\']
2.编译
如果一个匹配规则要多次使用,可以先将其编译,以后就不用每次去重复写匹配规则:
import re
comp = re.compile(r\'\d\')
print(comp.findall(\'abc1213,-45\'))
#执行结果
[\'1\', \'2\', \'1\', \'3\', \'4\', \'5\'
3.分组
re模块中分组的作用?
(1)判断是否匹配(2)灵活提取匹配到各个分组的值。
>>> import re
>>> print(re.search(r\'(\d+)-([a-z])\’,\’34324-dfsdfs777-hhh\’).group(0)) #返回整体
34324-d
>>> print(re.search(r\'(\d+)-([a-z])\’,\’34324-dfsdfs777-hhh\’).group(1)) #返回第一组
34324
>>> print(re.search(r\'(\d+)-([a-z])\’,\’34324-dfsdfs777-hhh\’).group(2)) #获取第二组
d
>>> print(re.search(r\'(\d+)-([a-z])\’,\’34324-dfsdfs777-hhh\’).group(3)) #不存在。报错“no such group”
Traceback (most recent call last):
File “<stdin>”, line 1, in <module>
IndexError: no such group