博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python3 如何优雅地使用正则表达式(详解三)
阅读量:4171 次
发布时间:2019-05-26

本文共 2164 字,大约阅读时间需要 7 分钟。

模块级别的函数

使用正则表达式也并非一定要创建模式对象,然后调用它的匹配方法。因为,re 模块同时还提供了一些全局函数,例如 match(),search(),findall(),sub() 等等。这些函数的第一个参数是正则表达式字符串,其他参数跟模式对象同名的方法采用一样的参数;返回值也一样,同样是返回 None 或者匹配对象。

  1. >>> print(re.match(r'From\s+', 'From_FishC.com'))
  2. None
  3. >>> re.match(r'From\s+', 'From FishC.com')
  4. < _sre.SRE_Match object; span=(0, 5), match='From '>
复制代码

其实,这些函数只是帮你自动创建一个模式对象,并调用相关的函数(上一篇的内容,还记得吗?)。它们还将编译好的模式对象存放在缓存中,以便将来可以快速地直接调用。



那我们到底是应该直接使用这些模块级别的函数呢,还是先编译一个模式对象,再调用模式对象的方法呢?这其实取决于正则表达式的使用频率,如果说我们这个程序只是偶尔使用到正则表达式,那么全局函数是比较方便的;如果我们的程序是大量的使用正则表达式(例如在一个循环中使用),那么建议你使用后一种方法,因为预编译的话可以节省一些函数调用。但如果是在循环外部,由于得益于内部缓存机制,两者效率相差无几。



编译标志


编译标志让你可以修改正则表达式的工作方式。在 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

这个标志使你的正则表达式可以写得更好看和更有条理,因为使用了这个标志,空格会被忽略(除了出现在字符类中和使用反斜杠转义的空格);这个标志同时允许你在正则表达式字符串中使用注释,
#
 符号后边的内容是注释,不会递交给匹配引擎(除了出现在字符类中和使用反斜杠转义的 
#
)。


下边是使用 re.VERBOSE 的例子,大家看下正则表达式的可读性是不是提高了不少:

  1. charref = re.compile(r"""
  2. & [#]                # 开始数字引用
  3. (
  4.      0[0-7]+         # 八进制格式
  5.    | [0-9]+          # 十进制格式
  6.    | x[0-9a-fA-F]+   # 十六进制格式
  7. )
  8. ;                   # 结尾分号
  9. """, re.VERBOSE)
复制代码

如果没有设置 VERBOSE 标志,那么同样的正则表达式会写成:
  1. charref = re.compile("&#(0[0-7]+|[0-9]+|x[0-9a-fA-F]+);")
复制代码

哪个可读性更加?相信大家心里有底了。

原文连接:

转载地址:http://ktyai.baihongyu.com/

你可能感兴趣的文章
2018.12.6
查看>>
人智导(四):约束满足问题
查看>>
2018.12.7
查看>>
2018.12.8
查看>>
2018.12.9
查看>>
2018.12.29
查看>>
2018.12.31
查看>>
2019.1.2
查看>>
2019.1.4
查看>>
2019.1.9
查看>>
2019.1.12
查看>>
Java语言程序设计与数据结构》编程练习答案(第二十章)(二)
查看>>
2019.2.25
查看>>
2019.2.26
查看>>
2019.2.27
查看>>
2019.2.28
查看>>
2019.2.29
查看>>
聊聊我当年在培训学校做开发的经历
查看>>
用Docker搭建Redis主从复制的集群
查看>>
盘点这些年我出的书,以及由此得到的收获
查看>>