详解Python正则表达式之: (?P…) named group 带命名的组

Python 2.7的手册中的解释:

(?P...)

Similar to regular parentheses, but the substring matched by the group is accessible within the rest of the regular expression via the symbolic group name name. Group names must be valid Python identifiers, and each group name must be defined only once within a regular expression. A symbolic group is also a numbered group, just as if the group were not named. So the group named id in the example below can also be referenced as the numbered group 1.

For example, if the pattern is (?P[a-zA-Z_]\w*), the group can be referenced by its name in arguments to methods of match objects, such asm.group('id') or m.end('id'), and also by name in the regular expression itself (using (?P=id)) and replacement text given to .sub() (using \g).

此处详细解释一下上述原文的意思:

声明:此处尽量称 group为“group”,而不翻译为 汉字的“组”,以便容易理解和去强化group本身的组的含义。

 

1.此处的(?P…),和普通的(?…):

【教程】详解Python正则表达式之: (…) group 分组

基本类似。区别在于,此处由于是给此group命名了,所以,后续(同一正则表达式内和搜索后得到的Match对象中),都可以通过此group的名字而去引用此group。

2. group的名字,当前需要是正常的Python标识符,即字母,数字,下划线等,即,没有特殊的字符。

3.同一正则表达式内,每个group的组名,是唯一的,不能重复。

4. 虽然此处group内命名了,但是其仍然和普通的

【教程】详解Python正则表达式之: (…) group 分组

中一样,可以通过索引号,即group(1),group(2)等等,去引用对应的group的。

很明显,按照正则内被命名的group的顺序,依次地

group(1)==group(name1)

group(2)==group(name2)

….

 

下面就整理出示例代码,用于演示,named group的用法,其中也包括了,相对要复杂一点的:

(1)命了名的group,在当前的正则表达式中,后续被(?P=name)的方式引用;

其中,详细注意事项,可参考:

【教程】详解Python正则表达式之: (?P=name) match earlier named group 匹配前面已命名的组

(2)re.sub()中后续通过\g方式被引用。

 

示例代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
【教程】详解Python正则表达式之: (?P...) named group 带命名的组
 
http://www.crifan.com/detailed_explanation_about_python_named_group
 
Version:    2012-11-12
Author:     Crifan
"""
 
import  re;
 
#如下教程所举例的代码,已去除重复的,关于group本身的解释。
#所以,请在参考学习下面代码之前,请确保已经对group的用法有所了解。
#如不了解,可参考:
#【教程】详解Python正则表达式之: (…) group 分组
#http://www.crifan.com/detailed_explanation_about_python_regular_express_about_group/
 
# 下列举例所用的字符串是来自于 http://janexyy.blogbus.com/logs/105359907.html 中的部分html代码
# 此处所采用的示例代码,参考自:
#http://code.google.com/p/blogs-to-wordpress/source/browse/trunk/libs/crifan/blogModules/BlogBlogbus.py
# -> extractTags()
reNamedGroupTestStr  =  u '标签:情侣电话粥' ;
 
# 1. (?P=name)
# 此处就是通过 (?P=name)的方式,来引用,正则表达式中,前面已经命名tagName的group的
foundTagA  =  re.search(u '.+?(?P=tagName)' , reNamedGroupTestStr);
print  "foundTagA=" ,foundTagA;  #foundTagA= <_sre.SRE_Match object at 0x00876D60>
 
if (foundTagA):
     # 2. mateched.group(name)
     # 可以通过之前给group命的名,来获得匹配到的值
     namedGroupStr  =  foundTagA.group( "tagName" );
     print  "namedGroupStr=" ,namedGroupStr;  #namedGroupStr= 情侣电话粥
 
     # 3. matched.group(N) == matched.group(name)
     # 此处,通过group的index,即group(1),group(2),...
     # 也可以获得和之前通过名字name获得的group的值
     # 通过名字或者索引号,两种方式都可以获得所需要的值,
     # 但是通过名字,更加准确,不会出现,当group太多而index容易混淆的问题
     group1Value  =  foundTagA.group( 1 );
     print  "Group(1): group1Value=" ,group1Value;  #Group(1): group1Value= 情侣电话粥
     
     # 4. \g in re.sub()
     # 在re.sub()中,通过\g的方式,引用前面已经命名为name的group的值
     substitutedStr  =  re.sub(u '.+?(?P=tagName)' , u '所捕获的tag值为:\g' , reNamedGroupTestStr);
     print  "Original string=%s, after substituted=%s" % (reNamedGroupTestStr, substitutedStr);  #Original string=标签:情侣电话粥, after substituted=所捕获的tag值为:情侣电话粥

 

【总结】

1. 一般多数是通过matched.group(name)的方式去获得对应所查找到的字符串的。

2. 关于匹配之前已经出现的字符串,可以使用:

(1)在re.search等中,使用(?P=name);

(2)在re.sub的被替换的字符串中,使用\g的方式获得之前已命名的group的值;

你可能感兴趣的:(python)