web开发和Django都会用到,很重要
1. 正则表达式的基本符号
首先我们必须了解匹配规则: help(re)可以查询规则
'.' 默认匹配除了换行符(\r,\n)以外任意一个字符,flag指定DOTALL,则也包括换行符
'^' 从字符开头匹配,flag指定MULTILINE,则是每行的开头
'$' 匹配字符的结尾,flag同'^'
'*' 匹配前一个字符0次或多次,只从字符串的起始开始匹配
'?' 匹配前一个字符0次或一次,只从字符串的起始开始匹配
'+' 匹配前一个字符1次或多次,可以匹配字符串中间的
'{m}' 匹配前一个字符m次
'{n,}' 匹配前一个字符n次以上。a{1,}相当于a+, a{0,}相当于a*
'{n,m}' 匹配前一个字符n到m次
'|' 匹配|左边或者|右边的字符
'(re)' 分组匹配('re'指代规则), re.search('(abc){2}a(123|45)','abcabca456c').group() # 这里(abc){2}就匹配的'abcabc'的意思
'(?: re)' 类似'(re)'但是不表示一个组
'[...]' 匹配范围,[a-zA-Z0-9]{3} # 匹配a-zA-Z0-9中的任意字符3次
'[^]' 取反,[^aeiou] #匹配除了'aeiou'字母以外的所有字符
'(?imx)' 正则表达式包含3种可选标志:i,m或x。只影响括号中的区域
'(?imx)' 正则表达式关闭i,m或x可选标志。只影响括号中的区域
'(?imx:aaa)' 在括号中使用i,m或x可选标志
'(?-imx)' 在括号中不使用i,m或x可选标志
'(?#...)' 注释
'(?= re)'
'(?! re)'
'(?> re)'
'\A' 只从字符开头匹配,相当于re.match()。re.search('\Aabc','abcadfa') 等同于 re.match('abc','abcadfa')
'\Z' 匹配字符的结尾,同$。re.search('dfa\Z','abcadfa')
'\d' 匹配数字,相当于[0-9]
'\D' 匹配非数字
'\w' 匹配[a-zA-Z0-9]
'\W' 匹配非[a-zA-Z0-9]
'\G'
'\b' 匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er' \
'\B' 匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'
'\1...\9' 匹配第n个分组的内容
'\10' 匹配第n个分组的内容,如果它经匹配。否则指的是八进制字符码的表达式
's' 匹配空白字符'\t','\n','\r'
'(?P
python import re str1 = '12341212' res = re.search('(?P<province>[0-9]{4})(?P<city>[0-9]{2})',str1) print(res.groups()) # 用groups()分组输出,返回tuple。 print(res.groupdict()) # 用<name>为key的字典,返回dict。 # 注意:res即使不用groupdict() 也可以直接当做字典来处理 print(res['city']) # 可以直接输出city的值
执行结果:
('1234', '12') {'province': '1234', 'city': '12'}
2. 正则模块 re
import re
-
re.match(pattern, string, flags=0)
用pattern从string的最开始就匹配。匹配到返回匹配对象,否则返回None。 -
re.search(pattern, string, flags=0)
找第一个匹配pattern的一个匹配的字符串,找到返回匹配对象,否则返回None。 -
re.findall(pattern, string, flags=0)
找到所有匹配的字符,返回列表。(可以用来分割字符串) -
re.split(pattern, string, maxsplit=0, flags=0)
用pattern的正则规则匹配的字符串,分割string。类似split()方法。import re str1 = 'sdfafa1231adasf23sdfa3fs' res1 = re.split('[0-9]{2}', str1) # pattern如果是多种字符可以用中括号括起来,比如[\*\-\/\+]指代'*','-','/','+'中的任意 print(res1) -
re.sub(pattern, repl, string, count=0, flags=0)
找到pattern的正则规则匹配的字符串,并用repl替换。最多替换count次import re str1 = 'sdfafa1231adasf23sdfa3fs' res1 = re.sub('[a-z]{3}', 'zzz', str1) print(res1) -
re.fullmatch(pattern, string, flags=0)
完全匹配。如果匹配了返回字符串,没有匹配的返回None。
import re
str1 = 'sdf'
res1 = re.fullmatch('[a-z]{3}', str1)
print(res1)
re.fullmatch('\w+@\w+\.(com|cn|edu)',"test@gmail.com") # 匹配邮箱
- re.compile(pattern, flags=0)
提前解析pattern。
在规则匹配的时候,内部是用规则内部的算法遍历每个匹配内容,在大量的数据情况下,效率可能会降低。
所以我们在匹配一个很大的数据时,可以先编译规则,再匹配。
import re
str1 = 'safgasdfaswrfgwerewr'
par = re.compile('[a-z]{3}')
res1 = par.search(str1)
print(res1)
- .group(n)
匹配规则可以用()来分组,group用于分组输出匹配结果。group(n)表示第n个()条件匹配的字符串。group(0)返回全部结果。
如果匹配规则没有(),只能使用group(0)
import re
str1 = "1sfasf3sf1abc44324"
print(re.search("([0-9]*)([a-z]*)([0-9]*)",str1).group(0)) # group(0)返回全部匹配结果
print(re.search("([0-9]*)([a-z]*)([0-9]*)",str1).group()) # 和group(0)相同,返回全部匹配结果
print(re.search("([0-9]*)([a-z]*)([0-9]*)",str1).group(1)) # group(1)返回pattern第一个()匹配的结果
print(re.search("([0-9]*)([a-z]*)([0-9]*)",str1).group(2)) # group(2)返回pattern第二个()匹配的结果
print(re.search("([0-9]*)([a-z]*)([0-9]*)",str1).group(3)) # group(3)返回pattern第三个()匹配的结果
-
.groups()
分组输出,参考'(?P...)' 分组匹配部分的例 -
.groupdict()
字典输出,参考'(?P...)' 分组匹配部分的例 -
正则条件的转义
正则表达式的条件(pattern)中,我们匹配有特殊含义字符的字符串时,需要用''来吧特殊含义字符转义成一般字符。
在python的一般字符串中的转义可以直接在字符串前使用'r'来标识字符串都是一般字符,可是似乎在正则表达式中只能用''来转义
import re
str1 = '1-2*((60-30+(-40/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))'
re.search(r'\([^()]+\)', str1).group() # 这里面[^()]的'^'表示取反,就是'无()'的意思
str2 = 'abc\n' # \n代表换行符
str3 = r'abc\n' # \n只是单纯的'\n'字符
-
其他用help(re)可以查一下。正则表达式很复杂
-
flags标志符
- re.I(IGNORECASE):匹配时忽略大小写(括号内是完整写法,下同)
- re.M(MULTILINE):多行模式,改变'','$'的行为,使'','$'匹配每一行的起始和结束。(匹配默认单行模式)
- re.S(DOTALL):改变'.'的行为,使'.'也能匹配换行符'\r\n',没有此标志符'.'不能匹配换行符。
- re.X(re.VERBOSE):可以给你的表达式写注释,使其更可读。
import re a = re.compile(r'''\d + # the integral part \. # the decimal point \d * # some fractional digits''', re.X) b = re.compile(r'\d+\.\d*')

浙公网安备 33010602011771号