2. 正则中特殊符号所代表的含义与例子
-
.
点点字符默认情况下表示任意字符,但是不包括
可以通过flag标志来声明
.
点匹配包括- 不包括换行
import re ret = re.match(".*","hello\ hello") print(ret.group())
- 包括换行
import re ret = re.match(".*","hello\ hello",re.DOTALL) print(ret.group())
re.DOTALL表示匹配所以字符。
- 不包括换行
-
^
行首^
表示这一行必须是以某种规则开始。^
在re.MULTILINE
模式中,表示按照- 普通行首
import re ret = re.match("^hel.*","hello\ hello") print(ret.group())
- 多行匹配
注意:这里有两个import re ret = re.match("^hel.* ^hel.*","hello\ hello",re.MULTILINE) print(ret.group())
^
,以及添加了re.MULTILINE
- 普通行首
-
$
行末尾筛选以某种规则结尾的字符串。
- 非多行
import re ret = re.findall(".+$","hello world\ hello") print(ret)
- 多行
import re ret = re.findall(".+$","hello world\ hello",re.MULTILINE) print(ret)
- 非多行
-
*
贪婪匹配尽量多的匹配,
*
等价于{0,INFINITY}
INFINITY表示无穷大,后面也一样。import re ret = re.findall(".*","hello world\ hello") print(ret)
-
+
多个尽量多的匹配,
+
等价于{1,INFINITY}
import re ret = re.findall(".+","hello world\ hello") print(ret)
-
?
0或1尽量多的匹配一个或0个,
.?
等价于{0,1}
import re ret = re.findall(".?","hello world\ hello") print(ret)
-
*? +? ??
非贪婪匹配,尽量少的匹配与上面三个相反。
- 贪婪模式
import re ret = re.findall("<.*>","<html></html>") print(ret)
- 非贪婪模式
import re ret = re.findall("<.*?>","<html></html>") print(ret)
- 贪婪模式
-
{m}
严格匹配m个重复字符import re ret = re.findall("a{1}","a<html>a</html>") print(ret)
-
{m,n}
至少m个,最多n个。贪婪匹配,尽可能多的匹配。
import re ret = re.findall("a{1,5}","aaaaa<html>a</html>") print(ret)
-
{m,n}?
非贪婪模式匹配import re ret = re.findall("a{1,5}?","aaaaa<html>a</html>") print(ret)
-
[]
集合中任选一个[]
只代表一个字符,即,括号之间的所有字符中的任意一个可以满足.并且这里面的所有的字符都失去它原来的特殊意义。
几种声明方式,一一列举,范围列举,集合,取反
- 一一列举
import re ret = re.findall("[a<]+","aaaaa<html>a</html>") print(ret)
- 范围罗列
import re ret = re.findall("[a-z]+","aaaaa<html>a</html>") print(ret)
- 集合
import re ret = re.findall("[\w]+","aaaaa<html>a</html>") print(ret)
- 取反
import re ret = re.findall("[^\w]+","aaaaa<html>a</html>") print(ret)
- 一一列举
-
|
多个表达式,从左往右匹配。import re ret = re.findall("(a|h)+","aaaaa<html>a</html>") print(ret)
-
(...)
创建组对于括号里面的表达式,匹配后形成一个组,供后面进行使用。可以通过
umber
的形式进行引用。如果要是用这个字面值,可以使用
( ) [(] [)]
。import re ret = re.search("(<html>)a\1","aaaaa<html>a<html>") print(ret)
-
(?...)
不创建组这种格式的表达式不会创建组,比如
(?:hello)
但是
(?P<name>...)
,这种是创建一个命名组。 -
(?aiLmsux)
局部按照特殊规则处理a 表示按照ASCII的方式匹配 i ignore case,表示忽略大小写匹配 L 本地依赖,有的国家的字符排序是 AaBb
m multi line 多行模式匹配 s 包含了seperator,即匹配所有,包括换行 u 按照unicode匹配 x 去掉注释和空格 -
(?:...)
不形成组
import re ret = re.search("(?:<html>)a(</html>)","aaaaa<html>a</html>") print(ret.groups())
-
(?aiLmsux-imsx:...)
嵌套与局部删除如前面用了i,但是我要在满足条件的嵌套组里面不适用i.
import re ret = re.search("(?i:(?:a|b)+(?-i:c+))","aaaaaAAAbbbccC") print(ret)
-
(?P<name>...)
创建一个命名组name符合python变量定义规则,只能定义一次,首先是一个组,然后再特殊化是一个命了名的组。
- 在同一个规则中引用
import re ret = re.search("(?P<header><html>)a\1","aaaaa<html>a<html>") print(ret,ret.groups())
import re ret = re.search("(?P<header><html>)a(?P=header)","aaaaa<html>a<html>") print(ret,ret.groups())
- 在结果中访问
import re ret = re.search("(?P<header><html>)a(?P=header)","aaaaa<html>a<html>") print(ret,ret.group("header"))
- 在
subn
方法中使用import re ret = re.subn("(?P<header><html>)","<\g<header>>","aaaaa<html>a<html>") print(ret)
import re ret = re.subn("(?P<header><html>)","<\g<1>>","aaaaa<html>a<html>") print(ret)
import re ret = re.subn("(?P<header><html>)","<\1>","aaaaa<html>a<html>") print(ret)
- 在同一个规则中引用
-
(?P=name)
与前面的相呼应。见前面的案例
-
(?#...)
一个注释,会被忽略
import re ret = re.search("(?P<header><html>)(?# this is a comment)","aaaaa<html>a<html>") print(ret,ret.groups())
-
(?=...)
是否以结尾,不消耗字符
import re ret = re.findall("(?P<header><html>)","aaaaa<html>a<html>") print(ret) ret = re.findall("(?P<header><html>(?=$))","aaaaa<html>a<html>") print(ret)
-
(?!...)
(?=...)
否定版本,不做演示。 -
(?<=...)
前缀,而且匹配长度相同,如果是多个匹配规则,长度也必须相同。
import re ret = re.findall("(?<=aa|bb)<html>","aaaaa<html>a<html>") print(ret)
-
(?<!...)
(?<=...)
的否定版本。不做演示。 -
(?(id/name)yes-pattern|no-pattern)
用于判断组是否存在,是则前面的匹配,否则后面的匹配。经常和
?
进行搭配import re ret = re.match("(<html>)(<html>)?(<html>)?a(?(3)</html>|)(?(2)</html>|)(?(1)</html>|$)", "<html><html>a</html></html>") print(ret)
上面的
(<html>)?
需要与后面的进行搭配。不然会出错。