※\序号:上一篇提到过,引用序号对应的子组所匹配的字符串,子组的序号从1开始计算,范围是 1~99
如果序号是以 0 开头,或者 3 位数字的长度。那么他不再被用于引用对应的子组,而是用于匹配八进制数字所表示的ASCII 码值对应的字符。
※\A :这个符号和托字符(^)在默认情况下是一样的,都表示匹配字符串的起始位置,也就是说,要是前面是 \A 或者 ^ 符号,那么这个字符就必须出现在字符串的开头,才能算是匹配。忘记了回去看上一篇( ^)的用法
※\Z :这个符号在默认情况下和 美元符号($)是一样的,都表示匹配字符串的结束位置。
(上面两个说的都是在默认情况下一样的,并不是说完全一样的。因为正则表达式还有一个 编译标志的设置,如果说你设置了一个 re.MULTILINE 标志,那么托字符(^)也匹配换行符之后的位置,同时,美元符号($)也匹配换行符之前的位置。但是呢,无论你设不设置这个标志,这个 \A 和 \Z 都只能匹配字符串的 开头 和 结束 位置。像这种匹配位置的字符,我们给它们一个名字,叫做临框断言,言外之意就是它们不会匹配任何字符,它们只用于定位一个位置。)
※\b :也是一个临框断言,匹配一个单词的边界,单词被定义为 Unidcode 的字母数字或下横线字符
(可以看到他匹配到了两个FishC,因为FishC_com 中的FishC的下横线也被认为是个单词,所以这里就不符合单词边界了。符号的话是属于单词边界,点号(.)感叹号(!)、括号都被认为是单词边界。)
※\B:与 \b 相反,匹配非单词边界。
(解析:就是py后面要有一个单词即Unidcode 的字母数字或下横线字符,所以不会匹配py空格,不会匹配py.,也不会匹配py!)
※\d:
1、 对于 Unicode(str 类型)模式:匹配任何一个数字,包括 [0-9] 和其他数字字符;如果开启了 re.ASCII 标志,就只匹配 [0-9]。
2、 对于 8 位(bytes 类型)模式(即字符串前边有个b):匹配 [0-9] 中任何一个数字。
※\D:匹配任何非 Unicode 的数字;与 \d 相反,如果开启了 re.ASCII 标志,则相当于匹配 [ ^ 0-9]。
※\s:
1、 对于 Unicode(str 类型)模式:匹配 Unicode 中的空白字符(包括 [ \t\n\r\f\v] 以及其他空白字符);如果开启了 re.ASCII 标志,就只匹配 [ \t\n\r\f\v]
(\f表示换页,\v表示垂直的tab键,垂直的制表符)
2、 对于 8 位(bytes 类型)模式:匹配 ASCII 中定义的空白字符,即 [ \t\n\r\f\v]
※\S:匹配任何非 Unicode 中的空白字符,其实就是与 \s 相反;如果开启了 re.ASCII 标志,则相当于匹配 [ ^\t\n\r\f\v]
※\w:
1、对于 Unicode(str 类型)模式:匹配任何 Unicode 的单词字符,基本上所有语言的字符都可以匹配,当然也包括数字和下横线;如果开启了 re.ASCII 标志,就只匹配 [a-zA-Z0-9_]
2、对于 8 位(bytes 类型)模式:匹配 ASCII 中定义的字母数字,即 [a-zA-Z0-9_]
(除了 空格 括号 点号 感叹号,其它的汉字、字母、下横线、数字 都是单词字符。)
※\W:匹配任何非 Unicode 的单词字符,其实就是与 \w 相反;如果开启了 re.ASCII 标志,则相当于 [ ^a-zA-Z0-9_]
※转义符号:
正则表达式还支持大部分 Python 字符串的转义符号:\a,\b,\f,\n,\r,\t,\u,\U,\v,\x, \\
注1:\b 通常用于匹配一个单词边界,只有在字符类中才表示“退格”
注2:\u 和 \U 只有在 Unicode 模式下才会被识别
注3:八进制转义(\数字)是有限制的,如果第一个数字是 0,或者如果有 3 个八进制数字,那么就被认为是八进制数;其他情况则被认为是子组引用;至于字符串,八进制转义总是最多只能是 3 个数字的长度
##编译正则表达式
(如果你需要重复地使用某个正则表表达式,那么你可以先把该正则表达式编译成模式对象。我们使用 re.compile() 方法来编译……)
※re.compile():compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。
(用了compile方法,就返回了一个正则表达式模式对象p,然后可以进行search方法的使用,把待匹配的字符串穿进去就好,也可以使用findall方法,可以看到,这是个模块级别的方法,我们是用模块来调用他的,因为模式对象p是由正则表达式编译过来的,所以第一个参数就省掉了,直接把待匹配的字符串传进去就OK了)
(有些朋友可能会问,你是使用 模块级别的方法效率比较高,还是说使用编译后的方法效率比较高,其实这个没有一定的定论,因为两种的优化差不多。这里,如果你至少需要使用一次正则表达式,你直接使用 模块级别的方法就可以了,但是呢,如果你下面要多次使用 这个正则表达式,你就可以先对其进行编译,后边再使用各种调用,这样更方便。我们以方便为主,既然学习Python,就不要多考虑效率的问题了,能优化的,他们都已经优化得差不多了。)
##编译标志
※编译标志让你可以修改正则表达式的工作方式。在 re 模块下,编译标志均有两个名字:完整名和简写,例如 IGNORECASE 简写是 I(如果你是 Perl 的粉丝,那么你有福了,因为这些简写跟 Perl 是一样的,例如 re.VERBOSE 的简写是 re.X)。另外,多个标志还可以同时使用(通过“|”),如:re.I | re.M 就是同时设置 I 和 M 标志。
下边列举一些支持的编译标志:
标志 | 含义 |
ASCII, A | 使得转义符号如 \w,\b,\s 和 \d 只能匹配 ASCII 字符 |
DOTALL, S | 使得 . 匹配任何符号,包括换行符 |
IGNORECASE, I | 匹配的时候不区分大小写 |
LOCALE, L | 支持当前的语言(区域)设置 |
MULTILINE, M | 多行匹配,影响 ^ 和 $ |
VERBOSE, X (for 'extended') | 启用详细的正则表达式 |
下面我们来详细讲解一下它们的含义:
A
ASCII
使得 \w,\W,\b,\B,\s 和 \S 只匹配 ASCII 字符,而不匹配完整的 Unicode 字符。这个标志仅对 Unicode 模式有意义,并忽略字节模式。
S
DOTALL
使得 . 可以匹配任何字符,包括换行符。如果不使用这个标志,. 将匹配除了换行符的所有字符。
I
IGNORECASE
字符类和文本字符串在匹配的时候不区分大小写。举个例子,正则表达式 [A-Z] 也将会匹配对应的小写字母,像 FishC 可以匹配 FishC,fishc 或 FISHC 等。如果你不设置 LOCALE,则不会考虑语言(区域)设置这方面的大小写问题。
L
LOCALE
使得 \w,\W,\b 和 \B 依赖当前的语言(区域)环境,而不是 Unicode 数据库。
区域设置是 C 语言的一个功能,主要作用是消除不同语言之间的差异。例如你正在处理的是法文文本,你想使用 \w+ 来匹配单词,但是 \w 只是匹配 [A-Za-z] 中的单词,并不会匹配 ‘é’ 或 ‘ç’。如果你的系统正确的设置了法语区域环境,那么 C 语言的函数就会告诉程序 ‘é’ 或 ‘ç’ 也应该被认为是一个字符。当编译正则表达式的时候设置了 LOCALE 的标志,\w+ 就可以识别法文了,但速度多少会受到影响。
M
MULTILINE
(^ 和 $ 我们还没有提到,别着急,后边我们有细讲…)
通常 ^ 只匹配字符串的开头,而 $ 则匹配字符串的结尾。当这个标志被设置的时候,^ 不仅匹配字符串的开头,还匹配每一行的行首;& 不仅匹配字符串的结尾,还匹配每一行的行尾。
X
VERBOSE
这个标志使你的正则表达式可以写得更好看和更有条理,因为使用了这个标志,空格会被忽略(除了出现在字符类中和使用反斜杠转义的空格);这个标志同时允许你在正则表达式字符串中使用注释,# 符号后边的内容是注释,不会递交给匹配引擎(除了出现在字符类中和使用反斜杠转义的 #)。
(因为稍微一个中等复杂度的正则表达式,你就会把它写成人模狗样,非常非常的复杂,因为正则表达式里 你不能随便加空格,因为空格它会被认为是其中的一个匹配元素,你不能加空格,不能加Tab 键,不能使用三重引号 换行,所以写出来的东西就会看起来很难理解。但是如果你开启了 VERBOSE,它就是支持 空格,支持Tab键,支持换行,也支持注释的。)
下边是使用 re.VERBOSE 的例子,大家看下正则表达式的可读性是不是提高了不少:
charref = re.compile(r"""
&[#] # 开始数字引用
(
0[0-7]+ # 八进制格式
| [0-9]+ # 十进制格式
| x[0-9a-fA-F]+ # 十六进制格式
)
; # 结尾分号
""", re.VERBOSE
如果没有设置 VERBOSE 标志,那么同样的正则表达式会写成:
charref = re.compile("&#(0[0-7]+|[0-9]+|x[0-9a-fA-F]+);")