python 正则表达式中的 Z(?ms)

在上篇 用 os.walk 和 fnmatch 删除指定目录下的pyc文件 中提到了fnmatch.translate(如下):
>>> import fnmatch

>>> pattern='*.py'

>>> print fnmatch.translate(pattern)

.
*\.py\Z(?ms)
由于之前对python的正则表达式缺乏了解,对结尾中的Z(?ms)不是很了解,在网上也没有查到专门的说明,于是在chinapy上提问,说明如下:
  • (?ms)是什么意思?

(?)算是Python正则表达式的修饰符, 可以有很多含义, 在这里?后面加上特定的字符以后, 它实现的作用是用来定义这个regex的一些属性, 其中:

"m"表示"多行模式", 默认情况下regex会将输入当做一整行处理, 有了这个多行模式后输入就会被按其中的换行符分开进行处理, 例子:

>>> re1 = re.compile(r'^(123)$')
>>> re2 = re.compile(r'^(123)$(?m)')
>>> re1.search('123\n123') is None
True
>>> re2.search('123\n123') is None
False

"s"表示"点('.')可以用来匹配任意字符, 包含换行符"\n" (默认情况下是不匹配换行符的)

关于Python Regex的用法, 请进一步参考官方文档.

  • 为什么不是简单的"$"?

试试下面的代码:

>>> import re
>>> r1 = re.compile(r'.*\.py\Z(?ms)')
>>> r2 = re.compile(r'.*\.py$')
>>> r1.search('1\n2.py').group()
'1\n2.py'
>>> r2.search('1\n2.py').group()
'2.py'

这个"1\n2.py"可能看上去有点奇怪, 但是在*nix下文件名确实可以包含换行符(Windows下不行), 单纯用$是无法匹配到正确结果的.

  • "Z"和"$"有什么区别?

在单行模式下基本没有区别, 它们都匹配行尾.

>>> s = "aaa\nbbb\nccc\ndddd"
>>> re.search(r'(\w)$', s).groups()
(
'd',)
>>> re.search(r'(\w)\Z', s).groups()
(
'd',)

多行模式下, "\Z"会匹配整个字符串的结尾, 而"$"会匹配每一个换行符的位置:

>>> s = "aaa\nbbb\nccc\ndddd"
>>> re.search(r'(\w)$(?ms)', s).groups()
(
'a',)
>>> re.search(r'(\w)\Z(?ms)', s).groups()
(
'd',)
最后,推荐一篇写python正则表达式比较全面的博客:Python正则表达式指南
posted @ 2011-04-10 21:50  TinyZ  阅读(1554)  评论(0编辑  收藏  举报