将命名捕获组替换为re.sub公司

2024-06-27 20:47:48 发布

您现在位置:Python中文网/ 问答频道 /正文

我想替换字符串中匹配的re模式的文本,可以使用re.sub()来完成这项工作。如果我在调用中将函数作为repl参数传递给它,那么它将按需要工作,如下所示:

from __future__ import print_function
import re

pattern = r'(?P<text>.*?)(?:<(?P<tag>\w+)>(?P<content>.*)</(?P=tag)>|$)'

my_str = "Here's some <first>sample stuff</first> in the " \
            "<second>middle</second> of some other text."

def replace(m):
    return ''.join(map(lambda v: v if v else '',
                        map(m.group, ('text', 'content'))))

cleaned = re.sub(pattern, replace, my_str)
print('cleaned: {!r}'.format(cleaned))

输出:

^{pr2}$

不过,从文档中看来,我应该可以通过向它传递一个包含对其中命名组的引用的替换字符串来获得相同的结果。但是,我的尝试没有成功,因为有时一个组是不匹配的,并且为它返回的值是None(而不是空字符串'')。在

cleaned = re.sub(pattern, r'\g<text>\g<content>', my_str)
print('cleaned: {!r}'.format(cleaned))

输出:

Traceback (most recent call last):
  File "test_resub.py", line 21, in <module>
    cleaned = re.sub(pattern, r'\g<text>\g<content>', my_str)
  File "C:\Python\lib\re.py", line 151, in sub
    return _compile(pattern, flags).sub(repl, string, count)
  File "C:\Python\lib\re.py", line 278, in filter
    return sre_parse.expand_template(template, match)
  File "C:\Python\lib\sre_parse.py", line 802, in expand_template
    raise error, "unmatched group"
sre_constants.error: unmatched group

我做错了什么或者不理解?在


Tags: 字符串textinpyrereturnmyline
2条回答
def repl(matchobj):
    if matchobj.group(3):
        return matchobj.group(1)+matchobj.group(3)
    else:
        return matchobj.group(1)

my_str = "Here's some <first>sample stuff</first> in the " \
        "<second>middle</second> of some other text."

pattern = r'(?P<text>.*?)(?:<(?P<tag>\w+)>(?P<content>.*)</(?P=tag)>|$)'
print re.sub(pattern, repl, my_str)

您可以使用re.sub的调用函数。在

编辑: cleaned = re.sub(pattern, r'\g<text>\g<content>', my_str)如果字符串的最后一位匹配,即of some other text.定义了\g<text>,但没有{},因为没有定义{}内容。但是你仍然要求re.sub去做它。所以它生成错误。如果您使用字符串"Here's some <first>sample stuff</first> in the <second>middle</second>",那么您的print re.sub(pattern,r"\g<text>\g<content>", my_str)将一直在这里定义\g<content>。在

如果我理解正确,您要删除< >之间的所有内容:

>>> import re

>>> my_str = "Here's some <first>sample stuff</first> in the <second>middle</second> of some other text."

>>> print re.sub(r'<.*?>', '', my_str)

Here's some sample stuff in the middle of some other text.

来解释一下这里发生了什么。。。r'<.*?>'

<查找第一个<

.然后接受任何字符

*接受任何字符任意次数

?将结果限制在尽可能短的时间内,如果没有这个,它将一直持续到最后一个>,而不是第一个可用的结果

>找到结束点>

然后,将这两点之间的所有内容替换为零。在

相关问题 更多 >