正则表达式
概念
在计算机科学中, 正则表达式就是用单个字符串描述或者和匹配一系列的某一个语法规则的字符串.(在代码中常简写为regex
/regexp
/RE
)
匹配字符串内容的一种规则,可以判断一个字符串是否匹配给定的格式,也可以从一个字符串中按指定格式提取信息
元字符
通配元字符
.
任意一个字符
可以多个连用,取消他的效果用 \
import re
a = '24k纯帅,帅'
my = re.findall(r'.帅',a) #在所有内容中查找
print(my)
#运行结果:
['纯帅', ',帅']
选择元字符
[]
列举一个字符以进行匹配
a = '24k纯帅,纯帅'
my = re.findall(r'[纯帅]',a)
print(my)
#运行结果:
['纯', '帅', '纯', '帅']
a|b
或
匹配1个a或1个b,返回所有匹配到内容
a = 'abcaabbcc'
my = re.findall(r'a|b',a)
print(my)
#运行结果:
['a', 'b', 'a', 'a', 'b', 'b']
锚点元字符
^
匹配开头,`### 匹配结尾
a = 'abbbbbbc'
start = re.findall(r'^a',a) #^匹配取开头
end = re.findall(r'c$',a) #$匹配取结尾
print(start,end)
#运行结果:
['a'] ['c']
重复元字符
{n}
控制字符匹配的个数
a = 'abbbbbbc'
my = re.findall(r'ab{6}c',a) #b匹配6次
print(my)
#运行结果:
['abbbbbbc']
还可以写成{n,m},从n个开始,m个结束
a = 'abbbbbbc'
my = re.findall(r'a.{1,10}c',a) #'.'匹配任意字符,至少1次最多10次
print(my)
#运行结果:
['abbbbbbc']
*
匹配任意个字符
注:可以是0个,会以空格代替0个,而且运行结果始终会多一个
a = 'ababbbbbbc'
my = re.findall(r'ab*c',a) # *修饰b,表示取任意个b
print(my)
#运行结果:
['abbbbbbc']
如果遇到匹配不上的字符会返回空格,而且会多一个空格
a = 'abaabbcc'
my = re.findall(r'a*',a) # *修饰a,表示取任意个a
print(my)
#运行结果:
['a', '', 'aa', '', '', '', '', '']
如果没有匹配到任何字符的话,则返回相同位置的空格,而且会多一个空格
a = 'abaabbcc'
my = re.findall(r'd*',a) # *修饰d,表示取任意个d
print(my)
#运行结果:
['', '', '', '', '', '', '', '', '']
+
匹配至少1个字符串
匹配不到会返回空的list
a = 'abcaabbcc'
my = re.findall(r'a+',a)
print(my)
#运行结果:
['a', 'aa']
?
每次最多匹配1个字符串
一次一次地匹配,注:可以是0个,会以空格代替0个,而且运行结果始终会多一个
a = 'abcaabbcc'
my = re.findall(r'a?',a)
print(my)
#运行结果:
['a', '', '', 'a', 'a', '', '', '', '', '']
贪婪与非贪婪模式
贪婪模式
尽可能多的取值,例如,*,+,?,{n,m},{n,}都是贪婪模式
a = 'abcaabbcc'
my = re.findall(r'ab*',a) #取0到无穷大个b,贪婪模式取无穷大个
print(my)
#运行结果:
['ab', 'a', 'abb']
非贪婪模式
尽可能少的取值,例如,*?,+?,??,{n,m}?,{n,}?都是非贪婪模式
a = 'abcaabbcc'
my = re.findall(r'ab*?',a) #取0到无穷大个b,非贪婪模式取0个
print(my)
#运行结果:
['a', 'a', 'a']
{n}既不是贪婪模式也不是非贪婪模式,因为它设定为固定长度
预定义字符
反向脱字符 ^ 写在中括号里,表示取反
预定义字符 | 说明 | 对等字符类 |
---|---|---|
\d digit | 任一数字字符 | [0-9] |
\D | 任一非数字字符 | [^0-9] |
\s space | 任一空白符 | [\t\n\x0B\f\r] |
\S | 任意非空白符 | [^\t\n\x0B\f\r] |
\w word | 任一字母数字字符 | [a-zA-Z0-9] |
\W | 任一非字母数字字符 | [^a-zA-Z0-9] |
\b 表示单词的边界(不是元字符)
a = '24k纯帅,帅'
my = re.findall(r'\b帅\b',a)
print(my)
#运行结果:
['帅']
提取字符
findall
任意位置匹配,返回全部匹配到的值
import re
a = '24k纯帅,帅'
my = re.findall(r'.帅',a)
print(my)
#运行结果:
['纯帅', ',帅']
match
从开头开始匹配,如果不是开头就匹配不到,并返回None
a = 'This is test text for search'
my = re.match(r'This',a)
print(my)
#运行结果:
<re.Match object; span=(0, 4), match='This'>
#span是匹配到的字符索引位置,match是匹配到的字符串
search
能够匹配任意位置,只能返回匹配到的第一个字符串
a = 'This is test text for search'
my = re.search(r's', a)
print(my)
#运行结果:
<re.Match object; span=(3, 4), match='s'>
#span是匹配到的字符索引位置,match是匹配到的字符串
group()方法:
可以将匹配到的字符串单独拿出来
a = 'abcdefghijklmn'
b = re.match(r'a(bc)(de)(f(g)h)i',a)
if b:
print(b.group()) #group()获取子组,默认括号中为0
print(b.group(1)) #括号中可以传入子组的序号,从1开始
print(b.group(2))
print(b.group(3))
print(b.group(4))
#运行结果:
abcdefghi
bc
de
fgh
g
除了获取匹配到的字符还可以获取匹配到值的位置
a = 'This is test text for search'
my = re.search(r'test', a)
print(my.span()) # span()返回匹配到值的位置
print(my.start()) # start()返回匹配到值的开头位置
print(my.end()) # end()返回匹配到值的结尾位置
#运行结果:
(8, 12)
8
12
替换字符
sub:替换字符,将某个字符串全部替换为指定字符串
a = 'sub替换前'
my = re.sub(r'前','后',a)
print(my)
#运行结果:
sub替换后
默认是全部替换,加上count=n就可以指定替换的次数
a = 'sub替换前,sub替换前'
my = re.sub(r'前','后',a,count=1) #count替换次数
print(my)
#运行结果:
sub替换后,sub替换前
延申:subn,会返回替换的次数,返回类型是tuple
a = 'sub替换前,sub替换前'
my = re.subn(r'前','后',a)
print(my)
#运行结果:
('sub替换后,sub替换后', 2) #2是替换的次数
常见用法
通过前后关键字匹配一些字符
str = '/**/jQuery19104222537217555642_1555121685832({"result_message":"验证码校验失败","result_code":"5"});'
message = re.findall(r'"result_message":"(.*?)",', post_cap.text)[0]
print(message)
# Result:
验证码校验失败
如果关键字距离想要的文字比较远,还可以这样用
message = re.findall(r'"result_me.*?"(.*?)",', post_cap.text)[0] #省略了中间的过长字符
print(message)
# Result:
验证码校验失败
?P<value>
?P的意思就是命名一个名字为value的组,匹配规则符合后面的/d+