欢迎光临散文网 会员登陆 & 注册

Python3 如何优雅地使用正则表达式(详解一)

2018-09-30 17:19 作者:荟呀荟学习  | 我要投稿

正则表达式介绍

       正则表达式(Regular expressions 也称为 REs,或 regexes 或 regex patterns)本质上是一个微小的且高度专业化的编程语言。它被嵌入到 Python 中,并通过 re 模块提供给程序猿使用。使用正则表达式,你需要指定一些规则来描述那些你希望匹配的字符串集合。

        正则表达式模式被编译成一系列的字节码,然后由一个 C 语言写的匹配引擎所执行。对于高级的使用,你可能需要更关注匹配引擎是如何执行给定的 RE,并通过一定的方式来编写 RE,以便产生一个可以运行得更快的字节码。本文暂不讲解优化的细节,因为这需要你对匹配引擎的内部机制有一个很好的理解。但本文的例子均是符合标准的正则表达式语法。

       正则表达式语言相对较小,并且受到限制,所以不是所有可能的字符串处理任务都可以使用正则表达式来完成。还有一些特殊的任务,可以使用正则表达式来完成,但是表达式会因此而变得非常复杂。在这种情况下,你可能通过自己编写 Python 代码来处理会更好些;尽管 Python 代码比一个精巧的正则表达式执行起来会慢一些,但可能会更容易理解。

字符匹配

      大多数字母和字符会匹配它们自身。举个例子,正则表达式bilibili 将完全匹配字符串 "bilibili"。同时我们可以采用不区分大小写方式使得我们可以匹配“BILIBILI”。


元字符

       有少数特殊的字符我们称之为元字符(metacharacter),它们并不能匹配自身,它们定义了字符类、子组匹配和模式重复次数等。下边是元字符的完整列表:

.   ^   $   *   +   ?   { }   [ ]   \   |   ( )

(一)首先介绍一下“.”

       它匹配除了换行符以外的任何字符。如果设置了 re.DOTALL 标志,. 将匹配包括换行符在内的任何字符。  例子如下所示。

“.”元字符的使用演示

(二)下面介绍一下“^”

       当我们需要匹配方括号中未列出的所有其他字符时,通常我们采用的方法是在类的开头添加一个脱字符号 ^ ,例如 [^8] 会匹配除了 '8' 之外的任何字符。例子如下所示。

   “^”元字符的使用演示

(三)下面介绍一下“$”

        $可以用来匹配输入字符串的结束位置。整个字符串结束字符,但如果最后一个是换行符那按照倒数第二个也可以匹配到,当然直接按照换行符也可以匹配到。需要注意的一点是:元字符在方括号中不会触发“特殊功能”,在字符类中,它们只匹配自身。例如 [CZY$] 会匹配任何字符 'C','Z','Y' 或 '$','$' 是一个元字符,但在方括号中它不表示特殊含义,它只匹配 '$' 字符本身。

“$”元字符的使用演示1
    "$"元字符的使用演示2

(四)接下来介绍一下“*”

       “*”能够轻松的匹配不同的字符集合,但 Python 字符串现有的方法却无法实现。然而天无绝人之路,正则表达式有另一个强大的功能,就是你可以指定 RE 部分被重复的次数。

       我们来看看 * 这个元字符,当然它不是匹配 '*' 字符本身,它用于指定前一个字符匹配零次或者多次。
       例如 ca*t 将匹配 ct(0 个字符 a),cat(1 个字符 a),caaat(3 个字符 a),等等。需要注意的是,由于受到 C 语言的 int 类型大小的内部限制,正则表达式引擎会限制字符 'a' 的重复个数不超过 20 亿个;不过,通常我们工作中也用不到那么大的数据。

“*”元字符的使用演示

(五)然后介绍一下“+”

       元字符是 +可以用于指定前一个字符匹配一次或者多次。要特别注意 * 和 + 的区别:* 匹配的是零次或者多次,所以被重复的内容可能压根儿不会出现;+ 至少需要出现一次。例如 ca+t 会匹配 cat 和 caaat,但不会匹配 ct。

"+"元字符的使用演示

(六)下面我们介绍一下“{}”

       最灵活的应该是元字符 {m, n}(m 和 n 都是十进制整数),上边讲到的几个元字符都可以使用它来表达,它的含义是前一个字符必须匹配 m 次到 n 次之间。例如 a/{1, 3}b 会匹配配 a/b,a//b 和 a///b。但不会匹配 ab;也不会匹配a////b。
       我们可以省略 m 或者 n,这样的话,引擎会假定一个合理的值代替。省略 m,将被解释为下限 0;省略 n 则会被解释为无穷大。例如 {, n} 相当于 {0, n};如果是 {m, } 相当于 {m, +无穷};如果是 {n},则是重复前一个字符 n 次。

        其实 *、+ 和 ? 都可以使用 {m, n} 来代替。{0,} 跟 * 是一样的;{1, } 跟 + 是一样的;{0, 1}跟 ? 是一样的。不过我们还是尽量使用 *、+ 和 ?,因为这些字符更短并且更容易阅读。

“{}”元字符的使用演示

(七)下面我们介绍一下“[]”

       它可以指定一个字符类用于存放你需要匹配的字符集合。可以单独列出需要匹配的字符,也可以通过两个字符和一个横杆 - 指定匹配的范围。例如 [abc] 会匹配字符 a,b 或 c;[a-c] 可以实现相同的功能。后者使用范围来表示与前者相同的字符集合。如果你想只匹配小写字母,你的 RE 可以写成 [a-z]。

“[]”元字符的使用演示

(八)下面我们介绍一下“\”

       或许最重要的元字符当属反斜杠 \ 了。跟 Python 的字符串规则一样,如果在反斜杠后边紧跟着一个元字符,那么元字符的“特殊功能”也不会被触发。例如你需要匹配符号 [ 或 \,你可以在它们前面加上一个反斜杠,以消除它们的特殊功能:\[,\\。
       反斜杠后边跟一些字符还可以表示特殊的意义,例如表示十进制数字,表示所有的字母或者表示非空白的字符集合。
       举例说明:\w 匹配任何字符。如果正则表达式以字节的形式表示,这相当于字符类 [a-zA-Z0-9_];如果正则表达式是一个字符串,\w 会匹配所有 Unicode 数据库中标记为字母的字符。你可以在编译正则表达式的时候,通过提供 re.ASCII 表示进一步限制 \w 的定义。

      下边列举一些反斜杠加字符构成的特殊含义:
       特殊字符含义\d匹配任何十进制数字;相当于类 [0-9]\D与 \d 相反,匹配任何非十进制数字的字符;相当于类 [^0-9]\s匹配任何空白字符(包含空格、换行符、制表符等);相当于类 [ \t\n\r\f\v]\S与 \s 相反,匹配任何非空白字符;相当于类 [^ \t\n\r\f\v]\w匹配任何字符,\W与 \w 相反\b匹配单词的开始或结束\B与 \b 相反。

       它们可以包含在一个字符类中,并且一样拥有特殊含义。例如 [\s,.] 是一个字符类,它将匹配任何空白字符(/s 的特殊含义),',' 或 '.'。

(九)下面我们介绍一下“|”

       “|”单独使用只匹配左右紧邻的表达式,可以和()结合使用。以下我以匹配IP地址为例解释一下“|”的用法。



Python3 如何优雅地使用正则表达式(详解一)的评论 (共 条)

分享到微博请遵守国家法律