【问题标题】:Python regex substitution using a dictionary使用字典的 Python 正则表达式替换
【发布时间】:2013-08-13 05:28:18
【问题描述】:

我有以下正则表达式来解析括号内的访问字符串并删除它们:

>>> a = 'a[b]cdef[g ]hi[ j]klmno[ p ]'
>>> re.sub(r'\[\s?(.*?)\s?\]',r'\1',a)
'abcdefghijklmnop'

但我想做的是让括号中的内容以字典为目标。假设我有以下字典:

d = {'b':2,'g':7,'j':10,'p':16}

当我运行我想要的正则表达式时,它应该打印字符串:'a2cdef7hi10klmno16'

但是,我不能简单地将sub 的替换部分设为d['\1'],因为会有KeyError: '\x01'

有没有什么简单的方法可以用响应正则表达式捕获的字典替换模式?

【问题讨论】:

    标签: python regex dictionary


    【解决方案1】:

    您可以使用format,假设a 不包含{...} 形式的子字符串:

    >>> import re
    >>> a = 'a[b]cdef[g ]hi[ j]klmno[ p ]'
    >>> d = {'b':2,'g':7,'j':10,'p':16}
    >>> 
    >>> re.sub(r'\[\s?(.*?)\s?\]',r'{\1}',a).format(**d)
    'a2cdef7hi10klmno16'
    

    或者你可以使用lambda:

    >>> re.sub(r'\[\s?(.*?)\s?\]', lambda m: str(d[m.group(1)]), a)
    'a2cdef7hi10klmno16'
    

    lambda 解决方案似乎要快得多:

    >>> from timeit import timeit
    >>>
    >>> setup = """
    ... import re
    ... a = 'a[b]cdef[g ]hi[ j]klmno[ p ]'
    ... d = {'b':2,'g':7,'j':10,'p':16}
    ... """
    >>>
    >>> timeit(r"re.sub(r'\[\s?(.*?)\s?\]',r'{\1}',a).format(**d)", setup)
    13.796708106994629
    >>> timeit(r"re.sub(r'\[\s?(.*?)\s?\]', lambda m: str(d[m.group(1)]), a)", setup)
    6.593755006790161
    

    【讨论】:

    • 在性能上是否有任何差异或使用其中一个的原因
    • @RyanSaxe 我认为 lambda 解决方案会更快,而且似乎更适合这种情况。
    【解决方案2】:

    使用正则表达式我不确定。但你可以这样做。

    a = 'a[b]cdef[g ]hi[ j]klmno[ p ]'
    result = re.sub(r'\[\s?(.*?)\s?\]',r'\1',a)
    newresult = result
    for char in result:
      value = d.get(char)
      if value:
        newresult = re.sub(char, value, newresult)
    print newresult
    

    【讨论】:

      【解决方案3】:

      Python 正则表达式替换函数可以采用任意替换函数替换为:

      import re
      d = {'b': 2, 'g': 7, 'j': 10, 'p': 16} 
      def repl_fn(matchobj):
        return str(d[matchobj.group(0)])
      regex = re.compile('[' + ''.join(d.iterkeys()) + ']')
      print regex.sub(repl_fn, 'abcdefghijklmnop')
      

      【讨论】:

        【解决方案4】:
        newstring = [(d[i] if i in d else i) for i in string]
        re.sub(r'\[\s?(.*?)\s?\]',r'\1',a)
        

        这应该通过首先替换字符,然后删除括号来完成您想要的操作,假设字典的值也是字符串。如果没有,只需将 d[i] 替换为 str(d[i])。

        【讨论】:

          猜你喜欢
          • 2023-02-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-12-22
          相关资源
          最近更新 更多