Python正则表达式--无捕获组和命名组
来源:互联网 发布:怎么安装cad2007软件 编辑:程序博客网 时间:2024/05/21 22:42
精心设计的 REs 也许会用很多组,既可以捕获感兴趣的子串,又可以分组和结构化 RE 本身。在复杂的 REs 里,追踪组号变得困难。有两个功能可以对这个问题有所帮助。它们也都使用正则表达式扩展的通用语法,因此我们来看看第一个。
无捕获组
Perl 5 对标准正则表达式增加了几个附加功能,Python 的 re 模块也支持其中的大部分。选择一个新的单按键元字符或一个以 "\" 开始的特殊序列来表示新的功能,而又不会使 Perl 正则表达式与标准正则表达式产生混乱是有难度的。如果你选择 "&" 做为新的元字符,举个例子,老的表达式认为 "&" 是一个正常的字符,而不会在使用 \& 或 [&] 时也不会转义。
Perl 开发人员的解决方法是使用 (?...) 来做为扩展语法。"?" 在括号后面会直接导致一个语法错误,因为 "?" 没有任何字符可以重复,因此它不会产生任何兼容问题。紧随 "?" 之后的字符指出扩展的用途,因此 (?=foo)
Python 新增了一个扩展语法到 Perl 扩展语法中。如果在问号后的第一个字符是 "P",你就可以知道它是针对 Python 的扩展。目前有两个这样的扩展: (?P<name>...) 定义一个命名组,(?P=name) 则是对命名组的逆向引用。如果 Perl 5 的未来版本使用不同的语法增加了相同的功能,那么 re 模块也将改变以支持新的语法,与此同时为了兼容性的目的而继续保持的 Python 专用语法。
现在我们看一下普通的扩展语法,我们回过头来简化在复杂 REs 中使用组运行的特性。因为组是从左到右编号的,而且一个复杂的表达式也许会使用许多组,它可以使跟踪当前组号变得困难,而修改如此复杂的 RE 是十分麻烦的。在开始时插入一个新组,你可以改变它之后的每个组号。
首先,有时你想用一个组去收集正则表达式的一部分,但又对组的内容不感兴趣。你可以用一个无捕获组: (?:...) 来实现这项功能,这样你可以在括号中发送任何其他正则表达式。
#!python>>> m = re.match("([abc])+", "abc")>>> m.groups()('c',)>>> m = re.match("(?:[abc])+", "abc")>>> m.groups()()
除了捕获匹配组的内容之外,无捕获组与捕获组表现完全一样;你可以在其中放置任何字符,可以用重复元字符如 "*" 来重复它,可以在其他组(无捕获组与捕获组)中嵌套它。(?:...) 对于修改已有组尤其有用,因为你可以不用改变所有其他组号的情况下添加一个新组。捕获组和无捕获组在搜索效率方面也没什么不同,没有哪一个比另一个更快。
命名组
更重要和强大的是命名组;与用数字指定组不同的是,它可以用名字来指定。
命令组的语法是 Python 专用扩展之一: (?P<name>...)。名字很明显是组的名字。除了该组有个名字之外,命名组也同捕获组是相同的。`MatchObject` 的方法处理捕获组时接受的要么是表示组号的整数,要么是包含组名的字符串。命名组也可以是数字,所以你可以通过两种方式来得到一个组的信息:
#!python>>> p = re.compile(r'(?P<word>\b\w+\b)')>>> m = p.search( '(((( Lots of punctuation )))' )>>> m.group('word')'Lots'>>> m.group(1)'Lots'命名组是便于使用的,因为它可以让你使用容易记住的名字来代替不得不记住的数字。这里有一个来自 imaplib 模块的 RE 示例:
#!pythonInternalDate = re.compile(r'INTERNALDATE "'r'(?P<day>[ 123][0-9])-(?P<mon>[A-Z][a-z][a-z])-'r'(?P<year>[0-9][0-9][0-9][0-9])'r' (?P<hour>[0-9][0-9]):(?P<min>[0-9][0-9]):(?P<sec>[0-9][0-9])'r' (?P<zonen>[-+])(?P<zoneh>[0-9][0-9])(?P<zonem>[0-9][0-9])'r'"')
很明显,得到 m.group('zonem') 要比记住得到组 9 要容易得多。
因为逆向引用的语法,象 (...)\1 这样的表达式所表示的是组号,这时用组名代替组号自然会有差别。还有一个 Python 扩展:(?P=name) ,它可以使叫 name 的组内容再次在当前位置发现。正则表达式为了找到重复的单词,(\b\w+)\s+\1 也可以被写成 (?P<word>\b\w+)\s+(?P=word):
#!python>>> p = re.compile(r'(?P<word>\b\w+)\s+(?P=word)')>>> p.search('Paris in the the spring').group()'the the'
- Python正则表达式--无捕获组和命名组
- Java 正则表达式 - 命名捕获组
- JDK7 正则表达式 捕获组命名
- jdk7正则表达式-命名捕获组(named capture)
- 正则表达式中的捕获组和非捕获组
- [疯狂Java]正则表达式:捕获组、反向引用、捕获组命名
- 正则表达式- 捕获组 非捕获组
- 正则表达式 捕获组理解
- java正则表达式捕获组
- .NET正则表达式的命名捕获
- 复习下Java正则表达式的捕获组和非捕获组
- 正则表达式中的捕获和非捕获
- 正则表达式中的捕获和非捕获
- JAVA正则表达式-捕获组与非捕获组
- 正则表达式一:捕获组与非捕获组
- JAVA正则表达式-捕获组与非捕获组
- JAVA正则表达式-捕获组与非捕获组
- JAVA正则表达式-捕获组与非捕获组
- 备份
- SqlServer中增加一列递增的序号
- Android 学习笔记——利用JNI技术在Android中调用、调试C++代码
- Python 特殊语法filter、map、reduce、lambda
- 计算最大序列和算法
- Python正则表达式--无捕获组和命名组
- 讯飞的语音识别技术VC源码
- SqlServer数据类型、C#SqlDbType对应关系及转换
- BoradcastReceiver 研究
- cocos2d-x配置Android项目相关事宜
- 关于 logging 的一些琐事
- git checkout -B android 5648d4e 不行啊。
- ONGL表达式的用法(精)
- Python的map函数实现代码