Python 正则表达式(二)
反斜杠的麻烦
在早期规定中,正则表达式用反斜杠字符 (”") 来表示特殊格式或允许使用特殊字符而不调用它的特殊用法。这就与 Python 在字符串中的那些起相同作用的相同字符产生了冲突。 让我们举例说明,你想写一个 RE 以匹配字符串 “section”,可能是在一个 LATEX 文件查找。为了要在程序代码中判断,首先要写出想要匹配的字符串。接下来你需要在所有反斜杠和元字符前加反斜杠来取消其特殊意义。
| 字符 | 阶段 |
| section | 要匹配的字符串 |
| \section | 为 re.compile 取消反斜杠的特殊意义 |
| “\\section” | 为字符串取消反斜杠 |
简单地说,为了匹配一个反斜杠,不得不在 RE 字符串中写 ‘\\’,因为正则表达式中必须是 “\”,而每个反斜杠按 Python 字符串字母表示的常规必须表示成 “\”。在 REs 中反斜杠的这个重复特性会导致大量重复的反斜杠,而且所生成的字符串也很难懂。 解决的办法就是为正则表达式使用 Python 的 raw 字符串表示;在字符串前加个 “r” 反斜杠就不会被任何特殊方式处理,所以 r”n” 就是包含”" 和 “n” 的两个字符,而 “n” 则是一个字符,表示一个换行。正则表达式通常在 Python 代码中都是用这种 raw 字符串表示。
| 常规字符串 | Raw 字符串 |
| “ab*” | r”ab*” |
| “\\section” | r”\section” |
| “\w+\s+\1″ | r”w+s+1″ |
执行匹配
一旦你有了已经编译了的正则表达式的对象,你要用它做什么呢?`RegexObject` 实例有一些方法和属性。这里只显示了最重要的几个,如果要看完整的列表请查阅 Python Library Reference
| 方法/属性 | 作用 |
| match() | 决定 RE 是否在字符串刚开始的位置匹配 |
| search() | 扫描字符串,找到这个 RE 匹配的位置 |
| findall() | 找到 RE 匹配的所有子串,并把它们作为一个列表返回 |
| finditer() | 找到 RE 匹配的所有子串,并把它们作为一个迭代器返回 |
如果没有匹配到的话,match() 和 search() 将返回 None。如果成功的话,就会返回一个 `MatchObject` 实例,其中有这次匹配的信息:它是从哪里开始和结束,它所匹配的子串等等。 你可以用采用人机对话并用 re 模块实验的方式来学习它。如果你有 Tkinter 的话,你也许可以考虑参考一下 Tools/scripts/redemo.py,一个包含在 Python 发行版里的示范程序。 首先,运行 Python 解释器,导入 re 模块并编译一个 RE:
#!python
Python 2.2.2 (#1, Feb 10 2003, 12:57:01)
>>> import re
>>> p = re.compile('[a-z]+')
>>> p
<_sre.SRE_Pattern object at 80c3c28>
现在,你可以试着用 RE 的 [a-z]+ 去匹配不同的字符串。一个空字符串将根本不能匹配,因为 + 的意思是 “一个或更多的重复次数”。 在这种情况下 match() 将返回 None,因为它使解释器没有输出。你可以明确地打印出 match() 的结果来弄清这一点。
#!python
>>> p.match("")
>>> print p.match("")
None
现在,让我们试着用它来匹配一个字符串,如 “tempo”。这时,match() 将返回一个 MatchObject。因此你可以将结果保存在变量里以便后面使用。
#!python >>> m = p.match( 'tempo') >>> print m <_sre.SRE_Match object at 80c4f68>
现在你可以查询 `MatchObject` 关于匹配字符串的相关信息了。MatchObject 实例也有几个方法和属性;最重要的那些如下所示:
| 方法/属性 | 作用 |
| group() | 返回被 RE 匹配的字符串 |
| start() | 返回匹配开始的位置 |
| end() | 返回匹配结束的位置 |
| span() | 返回一个元组包含匹配 (开始,结束) 的位置 |
试试这些方法不久就会清楚它们的作用了:
1 2 3 4 5 6 7 | #!python >>> m.group() 'tempo' >>> m.start(), m.end() (0, 5) >>> m.span() (0, 5) |
group() 返回 RE 匹配的子串。start() 和 end() 返回匹配开始和结束时的索引。span() 则用单个元组把开始和结束时的索引一起返回。因为匹配方法检查到如果 RE 在字符串开始处开始匹配,那么 start() 将总是为零。然而, `RegexObject` 实例的 search 方法扫描下面的字符串的话,在这种情况下,匹配开始的位置就也许不是零了。
1 2 3 4 5 6 7 8 9 | #!python >>> print p.match('::: message') None >>> m = p.search('::: message') ; print m >>> m.group() 'message' >>> m.span() (4, 11) |
在实际程序中,最常见的作法是将 `MatchObject` 保存在一个变量里,然后检查它是否为 None,通常如下所示:
1 2 3 4 5 6 7 | #!python p = re.compile( ... ) m = p.match( 'string goes here' ) if m: print 'Match found: ', m.group() else: print 'No match' |
两个 `RegexObject` 方法返回所有匹配模式的子串。findall()返回一个匹配字符串行表:
1 2 3 4 | #!python >>> p = re.compile('d+') >>> p.findall('12 drummers drumming, 11 pipers piping, 10 lords a-leaping') ['12', '11', '10'] |
findall() 在它返回结果时不得不创建一个列表。在 Python 2.2中,也可以用 finditer() 方法。
1 2 3 4 5 6 7 8 9 10 | #!python >>> iterator = p.finditer('12 drummers drumming, 11 ... 10 ...') >>> iterator >>> for match in iterator: ... print match.span() ... (0, 2) (22, 24) (29, 31) |
转载自:FLYBLOG [http://www.flyblog.info]
本文链接地址:http://www.flyblog.info/catprogramming/319.html
相关文章
回访来啦~一起努力!
我转载了你的一篇文章,我以前也是做技术的,现在自己做啦,做个友情链接吧 我的博客 http://www.bridal-gown.cn
回访来啦!支持一下,现在我都比较忙啦,比较少时间坐在电脑前了..希望你一切都顺利哦!