正则表达式
正则表达式是用来匹配字符串非常强大的工具,在其他编程语言中同样有正则表达式的概念。就其本质而言,正则表达式(或 RE)是一种小型的、高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。
#导入 re 模块 import re s = 'nick jenny nice' # 匹配方式(一) b = re.match(r'nick',s) q = b.group() print(q) # 匹配方式(二) # 生成Pattern对象实例,r表示匹配源字符串 a = re.compile(r'nick') print(type(a)) #<class '_sre.SRE_Pattern'> b = a.match(s) print(b) #<_sre.SRE_Match object; span=(0, 4), match='nick'> q = b.group() print(q) #被匹配的字符串放在string中 print(b.string) #nick jenny nice #要匹配的字符串放在re中 print(b.re) #re.compile('nick')
两种匹配方式区别在于:第一种简写是每次匹配的时候都要进行一次匹配公式的编译,第二种方式是提前对要匹配的格式进行了编译(对匹配公式进行解析),这样再去匹配的时候就不用在编译匹配的格式。
匹配规则:
. |
"." 匹配任意字符(除了 ) |
|
"" 转义字符 |
[...] |
"[...]" 匹配字符集 |
# "." 匹配任意字符(除了 ) a = re.match(r".","95nick") b = a.group() print(b) 输出结果:9 # [...] 匹配字符集 a = re.match(r"[a-zA-Z0-9]","123Nick") b = a.group() print(b) 输出结果:1
d |
匹配任何十进制数;它相当于类 [0-9] |
D |
匹配任何非数字字符;它相当于类 [^0-9] |
s |
匹配任何空白字符;它相当于类 [ fv] |
S |
匹配任何非空白字符;它相当于类 [^ fv] |
w |
匹配任何字母数字字符;它相当于类 [a-zA-Z0-9] |
W |
匹配任何非字母数字字符;它相当于类 [^a-zA-Z0-9] |
# d D 匹配数字/非数字 a = re.match(r"D","nick") b = a.group() print(b) 输出结果:n # s S 匹配空白/非空白字符 a = re.match(r"s"," ") b = a.group() print(b) 输出结果: # w W 匹配单词字符[a-zA-Z0-9]/非单词字符 a = re.match(r"w","123Nick") b = a.group() print(b) 输出结果:1 a = re.match(r"W","+-*/") b = a.group() print(b) 输出结果:+
* |
"*" 匹配前一个字符0次或者无限次 |
+ |
"+" 匹配前一个字符1次或者无限次 |
? |
"?" 匹配一个字符0次或者1次 |
{m} {m,n} |
{m} {m,n} 匹配前一个字符m次或者m到n次 |
*? +? ?? |
*? +? ?? 匹配模式变为非贪婪(尽可能少匹配字符串) |
# "*" 匹配前一个字符0次或者无限次 a = re.match(r"[A-Z][a-z]*","Aaaaaa123") #可以只匹配A,123不会匹配上 b = a.group() print(b) 输出结果:Aaaaaaa # “+” 匹配前一个字符1次或者无限次 a = re.match(r"[_a-zA-Z]+","nick") b = a.group() print(b) 输出结果:nick # “?” 匹配一个字符0次或者1次 a = re.match(r"[0-8]?[0-9]","95") #(0-8)没有匹配上9 b = a.group() print(b) 输出结果:9 # {m} {m,n} 匹配前一个字符m次或者m到n次 a = re.match(r"[w]{6,10}@qq.com","630571017@qq.com") b = a.group() print(b) 输出结果:630571017@qq.com # *? +? ?? 匹配模式变为非贪婪(尽可能少匹配字符串) a = re.match(r"[0-9][a-z]*?","9nick") b = a.group() print(b) 输出结果:9 a = re.match(r"[0-9][a-z]+?","9nick") b = a.group() print(b) 输出结果:9n
^ |
"^" 匹配字符串开头,多行模式中匹配每一行的开头 |
$ |
"$" 匹配字符串结尾,多行模式中匹配每一行的末尾 |
A |
A 仅匹配字符串开头 |
仅匹配字符串结尾 |
|
|
匹配一个单词边界,也就是指单词和空格间的位置 |
# "^" 匹配字符串开头,多行模式中匹配每一行的开头。 li = "nick njenny suo" a = re.search("^s.*",li,re.M) b = a.group() print(b) 输出结果:suo # "$" 匹配字符串结尾,多行模式中匹配每一行的末尾。 li = "nick jenny nick" a = re.search(".*y$",li,re.M) b = a.group() print(b) 输出结果:jenny # A 仅匹配字符串开头 li = "nickjennyk" a = re.findall(r"Anick",li) print(a) 输出结果:['nick'] # 仅匹配字符串结尾 li = "nickjennyk" a = re.findall(r"nick",li) print(a) 输出结果:[] # 匹配一个单词边界,也就是指单词和空格间的位置 a = re.search(r"nick","jenny nick car") b = a.group() print(b) 输出结果:nick
| |
"|" 匹配左右任意一个表达式 |
ab |
(ab) 括号中表达式作为一个分组 |
<number> |
<number> 引用编号为num的分组匹配到的字符串 |
(?P<key>vlaue) |
(?P<key>vlaue) 匹配到一个字典,去vlaue也可做别名 |
(?P=name) |
(?P=name) 引用别名为name的分组匹配字符串 |
# "|" 匹配左右任意一个表达式 a = re.match(r"nick|jenny","jenny") b = a.group() print(b) 输出结果: jenny # (ab) 括号中表达式作为一个分组 a = re.match(r"[w]{6,10}@(qq|163).com","630571017@qq.com") b = a.group() print(b) 输出结果: 630571017@qq.com # <number> 引用编号为num的分组匹配到的字符串 a = re.match(r"<([w]+>)[w]+</1","<book>nick</book>") b = a.group() print(b) 输出结果: <book>nick</book> # (?P<key>vlace) 匹配输出字典 li = 'nick jenny nnnk' a = re.match("(?P<k1>n)(?P<k2>w+).*(?P<k3>nw+)",li) print(a.groupdict()) 输出结果: {'k2': 'ick', 'k1': 'n', 'k3': 'nk'} # (?P<name>) 分组起一个别名 # (?P=name) 引用别名为name的分组匹配字符串 a = re.match(r"<(?P<jenny>[w]+>)[w]+</(?P=jenny)","<book>nick</book>") b = a.group() print(b) 输出结果: <book>nick</book>
模块方法介绍:
match |
从头匹配 |
search |
|
|
找到匹配,返回所有匹配部分的列表 |
finditer |
返回一个迭代器 |
sub |
将字符串中匹配正则表达式的部分替换为其他值 |
split |
根据匹配分割字符串,返回分割字符串组成的列表 |
######## 模块方法介绍 ######### # match 从头匹配 # search 匹配整个字符串,直到找到一个匹配 # findall 找到匹配,返回所有匹配部分的列表 # findall 加括号 li = 'nick jenny nick car girl' r = re.findall('nw+',li) print(r) #输出结果:['nick', 'nny', 'nick'] r = re.findall('(nw+)',li) print(r) #输出结果:['nick', 'nny', 'nick'] r = re.findall('n(w+)',li) print(r) #输出结果:['ick', 'ny', 'ick'] r = re.findall('(n)(w+)(k)',li) print(r) #输出结果:[('n', 'ic', 'k'), ('n', 'ic', 'k')] r = re.findall('(n)((w+)(c))(k)',li) print(r) #输出结果:[('n', 'ic', 'i', 'c', 'k'), ('n', 'ic', 'i', 'c', 'k')] # finditer 返回一个迭代器,和findall一样 li = 'nick jenny nnnk' a = re.finditer(r'nw+',li) for i in a: print(i.group()) # sub 将字符串中匹配正则表达式的部分替换为其他值 li = 'This is 95' a = re.sub(r"d+","100",li) print(a) li = "nick njenny ncar ngirl" a = re.compile(r"n") b = a.sub('cool',li,3) #后边参数替换几次 print(b) #输出结果: #coolick cooljenny coolcar ngirl # split 根据匹配分割字符串,返回分割字符串组成的列表 li = 'nick,suo jenny:nice car' a = re.split(r":| |,",li) #或| print(a) li = 'nick1jenny2car3girl5' a = re.compile(r"d") b = a.split(li) print(b) #输出结果: #['nick', 'jenny', 'car', 'girl', ''] #注意后边空元素
group() |
返回被 RE 匹配的字符串 |
groups() |
返回一个包含正则表达式中所有小组字符串的元组,从 1 到所含的小组号 |
groupdict() |
返回(?P<key>vlace)定义的字典 |
start() |
返回匹配开始的位置 |
end() |
返回匹配结束的位置 |
span() |
返回一个元组包含匹配 (开始,结束) 的索引位置 |
li = 'nick jenny nnnk' a = re.match("nw+",li) print(a.group()) a = re.match("(n)(w+)",li) print(a.groups()) a = re.match("(?P<k1>n)(?P<k2>w+).*(?P<k3>nw+)",li) print(a.groupdict()) 输出结果: nick ('n', 'ick') {'k1': 'n', 'k3': 'nk', 'k2': 'ick'} ----------------------------------------------- import re a = "123abc456" re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(0) #123abc456,返回整体 re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(1) #123 re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(2) #abc re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(3) #456 group(1) 列出第一个括号匹配部分,group(2) 列出第二个括号匹配部分,group(3)列出第三个括号匹配部分。
re.I |
使匹配对大小写不敏感 |
re.L |
做本地化识别(locale-aware)匹配 |
re.M |
多行匹配,影响 ^ 和 $ |
re.S |
使 . 匹配包括换行在内的所有字符 |
re.U |
根据Unicode字符集解析字符。这个标志影响 w, W, , B. |
re.X |
注释,会影响空格(无效了) |
#re.I 使匹配对大小写不敏感 a = re.search(r"nick","NIck",re.I) print(a.group()) #re.L 做本地化识别(locale-aware)匹配 #re.U 根据Unicode字符集解析字符。这个标志影响 w, W, , B. #re.S:.将会匹配换行符,默认.逗号不会匹配换行符 a = re.findall(r".","nick jenny",re.S) print(a) 输出结果: ['n', 'i', 'c', 'k', ' ', 'j', 'e', 'n', 'n', 'y'] #re.M:^$标志将会匹配每一行,默认^只会匹配符合正则的第一行;默认$只会匹配符合正则的末行 n = """12 drummers drumming, 11 pipers piping, 10 lords a-leaping""" p = re.compile("^d+") p_multi = re.compile("^d+",re.M) print(re.findall(p,n)) print(re.findall(p_multi,n))
常见正则列子:
匹配手机号:
# 匹配手机号 phone_num = '13001000000' a = re.compile(r"^1[d+]{10}") b = a.match(phone_num) print(b.group())
匹配IPv4:
# 匹配IP地址 ip = '192.168.1.1' a = re.compile(r"(((1?[0-9]?[0-9])|(2[0-4][0-9])|(25[0-5])).){3}((1?[0-9]?[0-9])|(2[0-4][0-9])|(25[0-5]))$") b = a.search(ip) print(b)
匹配email:
# 匹配 email email = '630571017@qq.com' a = re.compile(r"(.*){0,26}@(w+){0,20}.(w+){0,8}") b = a.search(email) print(b.group())