【问题标题】:Use '\g<index> or r'\index' as dict key when use re.sub? [duplicate]使用 re.sub 时使用 '\g<index> 或 r'\index' 作为 dict 键? [复制]
【发布时间】:2015-11-20 02:35:30
【问题描述】:

例如,我有以下字符串:

s = 'Name: @name, ID: @id'

现在我想用re.sub() 替换@name@id。我知道我可以使用 group 来捕获一些字符串,然后使用 '\g&lt;index&gt;'r'\index' 来使用它。

但现在我需要将它用作字典键,我有这个字典:

d = {'id': '20', 'name': 'Jon'}

我希望我能得到这个:

s = 'Name: Jon, ID: 20'

我也试过了:

>>> re.sub('@(\w+)', d[r'\1'], s)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
KeyError: '\\1'

>>> re.sub('@(\w+)', d['\g<1>'], s)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
KeyError: '\\g<1>'
>>> 

【问题讨论】:

    标签: python regex python-3.x


    【解决方案1】:

    Python 提供了一个string.Template class(另见PEP 292),它可以格式化与您正在使用的字符串非常相似的字符串。默认情况下,string.Template 类将 $ 识别为占位符。如果您将其更改为@(通过子类化string.Template),那么您可以通过调用substitutesafe_substitute 方法来执行替换:

    import string
    class MyTemplate(string.Template):
        delimiter = '@'
    
    content = 'Name: @name, ID: @id'
    d = {'id': '20', 'name': 'Jon'}
    template = MyTemplate(content)
    result = template.safe_substitute(**d)
    print(result)
    

    打印

    Name: Jon, ID: 20
    

    【讨论】:

    • 哇,以前不知道这个:D。但我的问题是关于 使用 '\g 或 r'\index' 作为使用 re.sub 时的 dict 键。所以我不能接受这个。但很高兴知道:)
    • 谢谢我不知道这个很酷的东西!帽子戏法!
    【解决方案2】:

    在这种情况下,您需要使用re.sub 的函数形式。对于您的基本用例,它可能很简单:

    re.sub(r'@(\w+)', lambda m: d[m.group(1)], s)
    

    如果逻辑更复杂,顶级def 是要走的路。基本上,根据re.sub docs,您传递callable 而不是str

    如果 repl 是一个函数,它会在每个不重叠的模式出现时调用。该函数采用单个匹配对象参数,并返回替换字符串。

    【讨论】:

    【解决方案3】:

    如果可以选择以不同方式格式化您的字符串,您可以这样做:

    >>> d = {'id': '20', 'name': 'Jon'}
    >>> 'Name: {name}, ID: {id}'.format(**d)
    'Name: Jon, ID: 20'
    

    【讨论】:

    • 但是我的字符串没有以这种格式格式化……但是一个很好的建议。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多