1 re匹配示例
# -*- coding:UTF8 -*- import re #查找匹配 text="验证码是安全的" pattern = re.compile(r'密码|验证码|安全') result = re.findall(pattern,text) #得到的是['验证码', '安全'] text="流量比较小" pattern = re.compile(r'流量.*[少低高小]|(简历量|曝光量|浏览量).*[少低高多大]')#两种匹配模式,通过|分开,其中()中的内容是或的关系,[]中的内容是任意一个,.*匹配无限多个任意字符 ret = re.search(pattern, text)#ret.group(0)表示匹配的整个句子,group是针对()来说的,第一个括号就是group(1),以此类推 print(ret.group(0))#流量比较小 text1="但是曝光量很高" ret = re.search(pattern, text1) print(ret.group(1))#但是曝光量很高 #分割字符串 text=r'one1two2three3four4five5' pattern = re.compile(r'd+') result = re.split(pattern, text)#['one', 'two', 'three', 'four', 'five', ''] #替换 text=r'流量比较小有人访问' pattern = re.compile(r'小') result = re.sub(pattern, ',但是',text)#流量比较,但是有人访问 print(result)
2单字符匹配规则
字符 | 功能 |
. | 匹配任意1个字符(除了 ) |
[] | 匹配[]中列举的字符,列举的字符或的关系;一些特殊字符变为普通字符,比如*是普通的*,没有特殊含义 |
d | 匹配数字,也就是0-9 |
D | 匹配非数字,也就是匹配不是数字的字符 |
s | 匹配空白符,也就是 空格 ab |
S | 匹配非空白符,s取反 |
w | 匹配单词字符, a-z, A-Z, 0-9, _ |
W | 匹配非单词字符, w取反 |
^ | 匹配字符串的开头。如"^(http:).*",匹配以http:开头的字符串 |
$ | 匹配字符串的末尾。如".*(.com)$",匹配以.com结尾的字符串 |
| |
或的关系。比如 C|cat 表示的是 C或cat; 如果要表示Cat或cat,则应该写为 (C|c)at。 |
3 表示数量的规则
字符 | 功能 |
* | 匹配前一个字符出现0次多次或者无限次,可有可无,可多可少 |
+ | 匹配前一个字符出现1次多次或则无限次,直到出现一次 |
? | 匹配前一个字符出现1次或者0次,要么有1次,要么没有 |
{m} | 匹配前一个字符出现m次 |
{m,} | 匹配前一个字符至少出现m次 |
{m,n} | 匹配前一个字符出现m到n次 |
.* | 贪婪匹配,就是尽可能多的匹配 |
.*? | 非贪婪匹配,只要满足要求,就停止。 |
4 分组与捕获
- (exp) :分组,并捕获该分组匹配到的文本
- (?:exp) :分组,但不捕获该分组匹配到的文本
(exp) :把括号内的正则作为一个分组,系统自动分配组号,可以通过分组号引用该分组;
(?P<name>exp) :定义一个命名分组,分组的正则是exp,系统为该分组分配分组号,可以通过分组名或分组号引用该分组;
(?:exp) :定义一个不捕获分组,该分组只在当前位置匹配文本,在该分组之后,无法引用该分组,因为该分组没有分组名,没有分组号,也不会占用分组编号;
字符 |
描述 |
示例 |
(?:pattern) |
匹配pattern,但不捕获匹配结果。 |
'industr(?:y|ies) 匹配'industry'或'industries'。 |
(?=pattern) |
零宽度正向预查,不捕获匹配结果。 |
'Windows (?=95|98|NT|2000)' 匹配 "Windows2000" 中的 "Windows" 不匹配 "Windows3.1" 中的 "Windows"。 |
(?!pattern) |
零宽度负向预查,不捕获匹配结果。 |
'Windows (?!95|98|NT|2000)' 匹配 "Windows3.1" 中的 "Windows" 不匹配 "Windows2000" 中的 "Windows"。 |
(?<=pattern) |
零宽度正向回查,不捕获匹配结果。 |
'2000 (?<=Office|Word|Excel)' 匹配 " Office2000" 中的 "2000" 不匹配 "Windows2000" 中的 "2000"。 |
(?<!pattern) |
零宽度负向回查,不捕获匹配结果。 |
'2000 (?<!Office|Word|Excel)' 匹配 " Windows2000" 中的 "2000" 不匹配 " Office2000" 中的 "2000"。 |
5 高效表达式建议
(1)每使用一个普通括号()而不是非捕获型括号(?:…),就会保留一部分内存等着你再次访问。这样的正则表达式、无限次地运行次数,无异于一根根稻草的堆加,终于能将骆驼压死。养成合理使用(?:…)括号的习惯。
(2)将一条复杂的正则表达式拆分为两条或多条简单的正则表达式,编程难度会降低,运行效率会提升。
(3)在适当的时候用上^,$,等等定位锚点,能有效提升找到成功匹配、淘汰不成功匹配的效率。
(4)在 Java 中使用正则表达式的时候我们需要先编译,所以应该尽量重用我们已经定义的正则表达式。
参考:《精通正则表达式》第5章、第6章
https://www.cnblogs.com/wuhong/archive/2011/02/18/1957017.html