最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【教程】详解Python正则表达式之: (?P<name>…) named group 带命名的组

Python re crifan 23602浏览 0评论

Python 2.7的手册中的解释:

(?P<name>...)

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<id>[a-zA-Z_]\w*), the group can be referenced by its name in arguments to methods of match objects, such as m.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<id>).

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

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

 

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

【教程】详解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<name>方式被引用。

 

示例代码如下:

#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
【教程】详解Python正则表达式之: (?P<name>...) named group 带命名的组
https://www.crifan.com/detailed_explanation_about_python_named_group

Version:    2012-11-12
Author:     Crifan
"""

import re;

#如下教程所举例的代码,已去除重复的,关于group本身的解释。
#所以,请在参考学习下面代码之前,请确保已经对group的用法有所了解。
#如不了解,可参考:
#【教程】详解Python正则表达式之: (…) group 分组
#https://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'标签:<a href="/tag/情侣电话粥/">情侣电话粥</a>';

# 1. (?P=name)
# 此处就是通过 (?P=name)的方式,来引用,正则表达式中,前面已经命名tagName的group的
foundTagA = re.search(u'.+?<a href="/tag/(?P<tagName>.+?)/">(?P=tagName)</a>', 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<name> in re.sub()
    # 在re.sub()中,通过\g<name>的方式,引用前面已经命名为name的group的值
    substitutedStr = re.sub(u'.+?<a href="/tag/(?P<tagName>.+?)/">(?P=tagName)</a>', u'所捕获的tag值为:\g<tagName>', reNamedGroupTestStr);
    print "Original string=%s, after substituted=%s"%(reNamedGroupTestStr, substitutedStr); #Original string=标签:<a href="/tag/情侣电话粥/">情侣电话粥</a>, after substituted=所捕获的tag值为:情侣电话粥

 

【总结】

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

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

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

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

转载请注明:在路上 » 【教程】详解Python正则表达式之: (?P<name>…) named group 带命名的组

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

网友最新评论 (2)

  1. 请问博主大大两个小问题: 1、如果不用命名group,那么substitutedStr = re.sub(u'.+?(.+?)', u'所捕获的tag值为:(请问这里该怎么写)', reNamedGroupTestStr); 2、substitutedStr = re.sub(u'.+?<a href="/tag/(?P.+?)/">(?P=tagName)', u'所捕获的tag值为:\g', reNamedGroupTestStr); 这里的(?P=tagName)是group(2)吧?因为这里的字符与(?P.+?)命名group的字符一致所以可以前去匹配,如果字符不一致就不可以用(?P=tagName)了吗?用新的(?P.+?)也可以吧
    山鬼6年前 (2019-05-08)回复
  2. 感谢~跟着码两遍就通了。虽然看起来有丢乱哈哈~
    山鬼6年前 (2019-05-08)回复
93 queries in 0.180 seconds, using 22.10MB memory