詳解Python正則表達式之: (?P…) named group 帶命名的組

原文地址:http://www.crifan.com/detailed_explanation_about_python_regular_express_named_group/

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 帶命名的組
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'標籤:<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的值;

發佈了21 篇原創文章 · 獲贊 48 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章