【问题标题】:re.sub in Python 3.3Python 3.3 中的 re.sub
【发布时间】:2013-05-23 06:34:02
【问题描述】:

我正在尝试将文本字符串从file1 的形式更改为file01。我对python真的很陌生,在尝试使用模式时无法弄清楚'repl'位置应该去什么。谁能帮帮我?

text = 'file1 file2 file3'

x = re.sub(r'file[1-9]',r'file\0\w',text) #I'm not sure what should go in repl.

【问题讨论】:

    标签: python regex python-3.x substitution


    【解决方案1】:

    你可以试试这个:

    >>> import re    
    >>> text = 'file1 file2 file3'
    >>> x = re.sub(r'file([1-9])',r'file0\1',text)
    'file01 file02 file03'
    

    [1-9] 周围的括号捕获匹配,它是第一个匹配。你会看到我在替换中使用了\1,意思是比赛中的第一个接球。

    另外,如果您不想为 2 位或更多位的文件添加零,您可以在正则表达式中添加 [^\d]

    x = re.sub(r'file([1-9](\s|$))',r'file0\1',text)
    

    现在我正在使用str.format()lambda 表达式重新访问此答案,因此提供了更多通用解决方案:

    import re
    fmt = '{:03d}'                 # Let's say we want 3 digits with leading zeroes
    s = 'file1 file2 file3 text40'
    result = re.sub(r"([A-Za-z_]+)([0-9]+)", \
                    lambda x: x.group(1) + fmt.format(int(x.group(2))), \
                    s)
    print(result)
    # 'file001 file002 file003 text040'
    

    关于 lambda 表达式的一些细节:

    lambda x: x.group(1) + fmt.format(int(x.group(2)))
    #         ^--------^   ^-^        ^-------------^
    #          filename   format     file number ([0-9]+) converted to int
    #        ([A-Za-z_]+)            so format() can work with our format
    

    我使用表达式[A-Za-z_]+ 假设文件名仅包含训练数字之外的字母和下划线。如果需要,请选择更合适的表达方式。

    【讨论】:

    • 您至少需要在最后一个示例中执行([^\d]|$),否则您无法匹配字符串中的最后一次出现。
    • @melwil 谢谢,现在修好了 :)
    • 现在你在第 1 组中匹配太多了,你在组中包含了空格,这使得file1 file2 变成了file01file02
    • @melwil 这一次,我预先测试了它,它比之前的file([1-9])([^\d]|$)效果更好。前一个会因为 [^\d] 而占用一个空间,而我必须添加更多字符来弥补这一点,而这个同时解决这两个问题。
    • 啊,是的,你当然是把空间放回去了。对此感到抱歉。
    【解决方案2】:

    要匹配末尾有单个数字的文件,请使用单词边界\b

    >>> text = ' '.join('file{}'.format(i) for i in range(12))
    >>> text
    'file0 file1 file2 file3 file4 file5 file6 file7 file8 file9 file10 file11'
    >>> import re
    >>> re.sub(r'file(\d)\b',r'file0\1',text)
    'file00 file01 file02 file03 file04 file05 file06 file07 file08 file09 file10 file11'
    

    【讨论】:

      【解决方案3】:

      在检查文件是否存在两位数时也可以使用\D|$,它决定是否将文件替换为file0

      以下代码也将有助于实现所需。

      重新导入

      text = 'file1 file2 file3 file4 file11 file22 file33 file1'

      x = re.sub(r'file([0-9] (\D|$))',r'file0\1',text)

      打印(x)

      【讨论】:

        【解决方案4】:

        您可以使用组来捕获您希望保留的部分,然后在替换文本中使用这些组。

         x = re.sub(r'file([1-9])',r'file0\1',text)
        

        匹配组是通过在正则表达式搜索中包含 ( ) 来创建的。然后,您可以将其与 \group\1 一起使用,因为我们希望插入第一个组。

        【讨论】:

          【解决方案5】:

          我相信以下内容会对您有所帮助。这样做的好处是它只会在 'file' 后面有一个数字的地方插入一个 '0'(通过边界 ['\b'] 特殊字符包含):

          text = 'file1 file2 file3'
          
          findallfile = re.findall(r'file\d\b', text)
          
          for instance in findallfile:
              textwithzeros = re.sub('file', 'file0', text)
          

          'textwithzeros' 现在应该是新版本的 'text' 字符串,每个数字前都带有 '0'。试试看!

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多