Python正则表达式操作指南(3)(转载)

网编 194 0

  模块级函数

  你不一定要产生一个 `RegexObject` 对象然後再调用它的方法;re 模块也提供了顶级函数调用如 match()、search()、sub() 等等。这些函数使用 RE 字符串作为第一个参数,而後面的参数则与相应 `RegexObject` 的方法参数相同,返回则要么是 None 要么就是一个 `MatchObject` 的实例。

  #!python

  >>> print re.match(r'From\s+', 'Fromage amk')

  None

  >>> re.match(r'From\s+', 'From amk Thu May 14 19:12:10 1998')

  <re.MatchObject instance at 80c5978>

  Under the hood, 这些函数简单地产生一个 RegexOject 并在其上调用相应的方法。它们也在缓存里保存编译後的对象,因此在将来调用用到相同 RE 时就会更快。

  你将使用这些模块级函数,还是先得到一个 `RegexObject` 再调用它的方法呢?如何选择依赖于怎样用 RE 更有效率以及你个人编码风格。如果一个 RE 在代码中只做用一次的话,那么模块级函数也许更方便。如果程序包含很多的正则表达式,或在多处复用同一个的话,那么将全部定义放在一起,在一段代码中提前编译所有的 REs 更有用。从标准库中看一个例子,这是从 xmllib.py 文件中提取出来的:

  #!python

  ref = re.compile( ... )

  entityref = re.compile( ... )

  charref = re.compile( ... )

  starttagopen = re.compile( ... )

  我通常更喜欢使用编译对象,甚至它只用一次,but few people will be as much of a purist about this as I am。

  编译标志

  编译标志让你可以修改正则表达式的一些运行方式。在 re 模块中标志可以使用两个名字,一个是全名如 IGNORECASE,一个是缩写,一字母形式如 I。(如果你熟悉 Perl 的模式修改,一字母形式使用同样的字母;例如 re.VERBOSE的缩写形式是 re.X。)多个标志可以通过按位 OR-ing 它们来指定。如 re.I | re.M 被设置成 I 和 M 标志:

  这有个可用标志表,对每个标志後面都有详细的说明。

  标志 含义

  DOTALL, S 使 . 匹配包括换行在内的所有字符

  IGNORECASE, I 使匹配对大小写不敏感

  LOCALE, L 做本地化识别(locale-aware)匹配

  MULTILINE, M 多行匹配,影响 ^ 和 $

  VERBOSE, X 能够使用 REs 的 verbose 状态,使之被组织得更清晰易懂

  I

  IGNORECASE

  使匹配对大小写不敏感;字符类和字符串匹配字母时忽略大小写。举个例子,[A-Z]也可以匹配小写字母,Spam 可以匹配 "Spam", "spam", 或 "spAM"。这个小写字母并不考虑当前位置。

  L

  LOCALE

  影响 \w, \W, \b, 和 \B,这取决于当前的本地化设置。

  locales 是 C 语言库中的一项功能,是用来为需要考虑不同语言的编程提供帮助的。举个例子,如果你正在处理法文文本,你想用 \w+ 来匹配文字,但 \w 只匹配字符类 [A-Za-z];它并不能匹配 "é" 或 "?"。如果你的系统配置适当且本地化设置为法语,那么内部的 C 函数将告诉程序 "é" 也应该被认为是一个字母。当在编译正则表达式时使用 LOCALE 标志会得到用这些 C 函数来处理 \w 後的编译对象;这会更慢,但也会象你希望的那样可以用 \w+ 来匹配法文文本。

  M

  MULTILINE

  (此时 ^ 和 $ 不会被解释; 它们将在 4.1 节被介绍.)

  使用 只匹配字符串的开始,而 $ 则只匹配字符串的结尾和直接在换行前(如果有的话)的字符串结尾。当本标志指定後, 匹配字符串的开始和字符串中每行的开始。同样的, $ 元字符匹配字符串结尾和字符串中每行的结尾(直接在每个换行之前)。

  S

  DOTALL

  使 "." 特殊字符完全匹配任何字符,包括换行;没有这个标志, "." 匹配除了换行外的任何字符。

  X

  VERBOSE

  该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。当该标志被指定时,在 RE 字符串中的空白符被忽略,除非该空白符在字符类中或在反斜杠之後;这可以让你更清晰地组织和缩进 RE。它也可以允许你将注释写入 RE,这些注释会被引擎忽略;注释用 "#"号 来标识,不过该符号不能在字符串或反斜杠之後。

  举个例子,这里有一个使用 re.VERBOSE 的 RE;看看读它轻松了多少?

  #!python

  charref = re.compile(r"""

  &[[]] # Start of a numeric entity reference

  [0-9]+[^0-9] # Decimal form

  | 0[0-7]+[^0-7] # Octal form

  | x[0-9a-fA-F]+[^0-9a-fA-F] # Hexadecimal form

  """, re.VERBOSE)

  没有 verbose 设置, RE 会看起来象这样:

  #!python

  charref = re.compile("([0-9]+[^0-9]"

  "|0[0-7]+[^0-7]"

  "|x[0-9a-fA-F]+[^0-9a-fA-F])")

  在上面的例子里,Python 的字符串自动连接可以用来将 RE 分成更小的部分,但它比用 re.VERBOSE 标志时更难懂。

  更多模式功能

  到目前为止,我们只展示了正则表达式的一部分功能。在本节,我们将展示一些新的元字符和如何使用组来检索被匹配的文本部分。

  更多的元字符

  还有一些我们还没展示的元字符,其中的大部分将在本节展示。

  剩下来要讨论的一部分元字符是零宽界定符(zero-width assertions)。它们并不会使引擎在处理字符串时更快;相反,它们根本就没有对应任何字符,只是简单的成功或失败。举个例子, \b 是一个在单词边界定位当前位置的界定符(assertions),这个位置根本就不会被 \b 改变。这意味着零宽界定符(zero-width assertions)将永远不会被重复,因为如果它们在给定位置匹配一次,那么它们很明显可以被匹配无数次。

  可选项,或者 "or" 操作符。如果 A 和 B 是正则表达式,A|B 将匹配任何匹配了 "A" 或 "B" 的字符串。| 的优先级非常低,是为了当你有多字符串要选择时能适当地运行。Crow|Servo 将匹配"Crow" 或 "Servo", 而不是 "Cro", 一个 "w" 或 一个 "S", 和 "ervo"。

  为了匹配字母 "|",可以用 \|,或将其包含在字符类中,如[|]。

  匹配行首。除非设置 MULTILINE 标志,它只是匹配字符串的开始。在 MULTILINE 模式里,它也可以直接匹配字符串中的每个换行。

  例如,如果你只希望匹配在行首单词 "From",那幺 RE 将用 ^From。

  #!python

  >>> print re.search('^From', 'From Here to Eternity')

  <re.MatchObject instance at 80c1520>

  >>> print re.search('^From', 'Reciting From Memory')

  None

  匹配行尾,行尾被定义为要么是字符串尾,要么是一个换行字符後面的任何位置。

  #!python

  >>> print re.search('}$', '{block}')

  <re.MatchObject instance at 80adfa8>

  >>> print re.search('}$', '{block} ')

  None

  >>> print re.search('}$', '{block}\n')

  <re.MatchObject instance at 80adfa8>

  匹配一个 "$",使用 \$ 或将其包含在字符类中,如[$]。

  \A

  只匹配字符串首。当不在 MULTILINE 模式,\A 和 实际上是一样的。然而,在 MULTILINE 模式里它们是不同的;\A 只是匹配字符串首,而 还可以匹配在换行符之後字符串的任何位置。

  \Z

  Matches only at the end of the string.

  只匹配字符串尾。

  \b

  单词边界。这是个零宽界定符(zero-width assertions)只用以匹配单词的词首和词尾。单词被定义为一个字母数字序列,因此词尾就是用空白符或非字母数字符来标示的。

  下面的例子只匹配 "class" 整个单词;而当它被包含在其他单词中时不匹配。

  #!python

  >>> p = re.compile(r'\bclass\b')

  >>> print p.search('no class at all')

  <re.MatchObject instance at 80c8f28>

  >>> print p.search('the declassified algorithm')

  None

  >>> print p.search('one subclass is')

  None

  当用这个特殊序列时你应该记住这里有两个微妙之处。第一个是 Python 字符串和正则表达式之间最糟的冲突。在 Python 字符串里,"\b" 是反斜杠字符,ASCII值是8。如果你没有使用 raw 字符串时,那幺 Python 将会把 "\b" 转换成一个回退符,你的 RE 将无法象你希望的那样匹配它了。下面的例子看起来和我们前面的 RE 一样,但在 RE 字符串前少了一个 "r" 。

  #!python

  >>> p = re.compile('\bclass\b')

  >>> print p.search('no class at all')

  None

  >>> print p.search('\b' + 'class' + '\b')

  <re.MatchObject instance at 80c3ee0>

  第二个在字符类中,这个限定符(assertion)不起作用,\b 表示回退符,以便与 Python 字符串兼容。

  \B

  另一个零宽界定符(zero-width assertions),它正好同 \b 相反,只在当前位置不在单词边界时匹配。

  本文源自:ht tp://w w w.c svt.ne t/

标签: #字符 #例子 #正则表达式 #字符串 #>

  • 评论列表

留言评论