概念
正则表达式是可以选择含有某种格式的文本。它用一定的语句匹配符合一定规则的字符串。
正则表达式中的字符
元字符 metacharacter
- \b 匹配一个位置,单词的前 / 后 边界
- \d 匹配数字 [0 - 9]
- \D 匹配非数字的字符 [^0-9]
- \w 匹配数字[0-9],字母[a-zA-Z],下划线_,汉字,其他语言
- \W 匹配除4以外的任意字符
- . 除换行符以外任意字符
- \s 匹配任意的空白符
- \S匹配非空白
- % 匹配字符串结尾
- \f \n \r \t 匹配换页,换行,回车,制表符
[XXX]
- [abc] 匹配a,b,c中的任意一个字符
- [a-z] 匹配a-z的任意一个字符
- [a-zA-Z]匹配a-z和A-Z的任意一个字符
- 字符前加 ^ 表示不在后面规定的范围内的字符
限定符(表示数量,出现次数)
- * 左边的字符可以出现任意次(包括0次)
- +左边的字符可以出现任意次(不包括0次)
- \?左边的字符可以出现 0 次或 1 次
- {m} m ≥ 0 左边的字符出现m次
- {m,} m ≥ 0 左边的字符出现 ≥m 次
- {m,n} m,n ≥ 0 左边的字符出现 m~n次(包括 m 和 n)
注:单独的 ? 跟在这几个符号后表示贪婪模式,即该范式尽可能少的出现。例如对于字符串"abbb","ab+"匹配所有b,而加入?后,即"ab\*?"匹配一个b
使用时,一般可以将限定符放到元字符的后面,表示前面的某个元字符重复几次。
边界,不匹配字符
\A \Z 字符起始 结束位置
^ $ 字符起始 结束位置(包括\t \n之后的起始 结束位置)
分组(XXX)
1.括号里的是一个分组。如果有多个分组,从左到右从1开始编号。
2.括号后 \i 或 r’\i 要求前面的字符后跟着 i 号分组在本次匹配到的值,少一个字符都无法运行出来。
q = '(((mn+)o)p)\\1' #r'(((mn+)o)p)\1'
x2= re.match(q,'mnnnnopmnnnnop')
print(x2.group())
# mnnnnopmnnnnop
\1 表示再完全重复一遍第一个分组。少一个 n 都不能完全运行出来。
3.分组后可以加量词。但是每次匹配的模式可以不同。
r = '(((mn*)o)+p)'
x3 = re.match(r,'mnomnnomnnnopuh')
print(x3.group())
# mnomnnomnnnop
例如加上量词 + 可以看到每次不一定要匹配的n的个数相同。不同于上一种情况。
正则表达式内置函数
使用正则表达式时首先导入
import re
- re.compile 有两个参数,第一个参数是要匹配的范式,第二个参数是标志。编译正则表达式模式,返回一个正则对象的模式。
ss = "夏洛克 有华生,夏洛克 很厉害"
cc = re.compile('\w*夏洛克\w*')
print(cc.findall(ss)) #查找所有包含'夏洛克'的单词
#返回 ['夏洛克', '夏洛克']
以下函数有三个参数,第一个参数是要匹配的范式,第二个参数是要匹配的字符,第三个参数是标志位。
- re.match 匹配字符串起始位置
m = re.match('ac','acfha') #查询起始字符是ac
m.group()
## 返回'ac'
- re.search 匹配整个字符串直到找到第一个匹配值返回
注:match和search一旦匹配成功,就是一个match object对象,而match object对象有以下方法:
group() 返回被 RE 匹配的字符串
start() 返回匹配开始的位置
end() 返回匹配结束的位置
span() 返回一个元组包含匹配 (开始,结束) 的位置
s = re.search('[a-zA-Z]','faaaaac495dddfha') #匹配大小写英语字母,找到第一个就返回
s.group()
#'f'
- re.findall 匹配成功的字符串会返回一个列表
f = re.findall('\d+','a1b2c3') #返回数字
f
#['1', '2', '3']
- re.finditer 返回一个顺序访问每一个匹配结果的迭代器。
iter = re.finditer(r'\d+','There are 35 girls and 12 boys') #返回数字
for i in iter:
print(i)
print(i.group())
print(i.span())
#<re.Match object; span=(10, 12), match='35'>
#35
#(10, 12)
#<re.Match object; span=(23, 25), match='12'>
#12
#(23, 25)
- re.split
split(pattern, string, maxsplit=0, flags=0)
第一个参数:分隔符。
第二个参数:要分割的字符串。
第三个参数:最大分割次数。
<0不分割,=0分割无限次,>0分割maxsplit次。
ss = '夏洛克 有华生 夏洛克 很厉害'
mm = re.split('\s',ss)
print(mm)
#['夏洛克', '有华生,夏洛克', '很厉害']
- re.sub
sub(pattern, repl, string, count=0, flags=0)
pattern:要寻找的模式
repl:代表replacement,要替换的字符。也就是用repl去替换pattern
count:要替换的最大次数;count 必须是非负整数。
b = "a468a b468a486a"
n1 = re.sub('\d+','5',b,count=2)
print(n1)
#a5a b5a486a
n2 = re.sub('\d+','5',b,count=0)
print(n2)
#a5a b5a5a