论一只爬虫的自我修养7:正则表达式3

       ※\序号:上一篇提到过,引用序号对应的子组所匹配的字符串,子组的序号从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]+);")
发布了247 篇原创文章 · 获赞 116 · 访问量 28万+

猜你喜欢

转载自blog.csdn.net/w15977858408/article/details/104125881