【问题标题】:Get number of characters matched in regex获取正则表达式中匹配的字符数
【发布时间】:2014-07-24 21:29:28
【问题描述】:

我有一个缩进一个空格缩进的文件:

Level1 with some text
 Level2 
Level1 
  Level3 and its text

我想缩进 4 个空格。我想了一个正则表达式来匹配起始空间^(\s)*。但是,我不知道如何将其替换为“为找到的每个空间应用一个选项卡”。

我的预期输出是:

Level1 with some text
    Level2 
Level1 
        Level3 and its text

是否存在类似\t*len(\1) 的东西?

编辑:我会很欣赏基于正则表达式的解决方案,因为我的目标是在具有正则表达式替换功能的 SublimeText 编辑器中使用它。

【问题讨论】:

    标签: python regex sublimetext3


    【解决方案1】:

    我认为 Python 正则表达式引擎不支持这一点,但由于您提到使用 Sublime Text,您可以使用 \G anchor,它与上一个匹配结束后立即匹配的位置。

    Find What:     (^|\G)\s
    Replace With:  \t
    

    此模式将匹配紧跟在前一个匹配项行开头的任何单个空白字符。

    【讨论】:

    • 有趣!我不知道\G 锚。确实,在我的用例中它会完美运行!
    • +1 但鲜为人知的事实是 \G 匹配字符串的开头,因此您可以简化正则表达式。实际上很烦人,例如参见this demo——在 Sublime 中也是如此。我经常不得不使用(?:(?!^)\G)之类的东西
    【解决方案2】:

    我认为正则表达式对于这个问题可能是矫枉过正的。为什么不尝试这样的事情(假设您的原始文本文件名为test.txt),

    #new_space = '\t'
    new_space = '    '
    f = open( 'new.txt', 'w' )
    for line in open( 'test.txt', 'r' ):
        nw = len(line) - len(line.lstrip())
        if nw != 0:
            f.write( nw*new_space + line.lstrip() )
        else:
            f.write( line ) 
    f.close()
    

    【讨论】:

    • 我编辑了我的答案,性能不是我关心的问题。我想从 sublime 编辑器中直接修改文件。
    • 这可能不适用于多个级别。也许您可以将其扩展一点,以适当的制表符数量(或 4 个空格)替换行开头的多个空格?
    • @Cqnqrd 那么这个问题与 Python 有什么关系?
    • @Gabriel 因为 Sublime 是用 Python 编写的,我猜一个有效的 Python 解决方案可以在 Sublime 中工作?
    • @rvraghav93,谢谢,已更新以处理任意数量的空白
    【解决方案3】:

    你可以这样做:

    code = """Level1 with some text
     Level2 
    Level1 
      Level3 and its text"""
    
    TAB = "\t" # You could also give TAB="    " ( 4 spaces )
    
    # Spaces at line start are replaced with TAB
    code = code.replace('\n ', '\n'+TAB)
    
    while code.find(TAB+" ") is not -1 :
        # For multilevel indentation
        code = code.replace(TAB+' ', TAB*2)
    
    print code
    

    输出:

    Level1 with some text
        Level2 
    Level1 
            Level3 and its text
    

    【讨论】:

      【解决方案4】:

      如果你特别想要空格,试试这个表达式。 s/ /\t/g; 您可以将空格“”替换为其他一些正则表达式字符以获得更大的灵活性(例如“\s”)。

      在 perl 中它可能是..

      $i =~ s/ /\t/g; 打印 "$i\n";

      我刚刚注意到“python”标签。很抱歉 perl 示例和 python 中缺少一个示例。

      【讨论】:

        【解决方案5】:

        您可以使用积极的后向断言:

        text="""Level1 with some text
                 Level2 
                Level1 
                  Level3 and its text"""
        
        
        re.sub(r'(?<=\s) ', r'\t', text, flags=re.M)
        

        这会将前面有空格/换行符的每个空格替换为\t,因此第 3 级将有两个制表符,而第 2 级将只有一个。单词之间的空格将不受影响。输出:

        Level1 with some text
            Level2 
        Level1 
                Level3 and its text
        

        【讨论】:

          猜你喜欢
          • 2013-06-12
          • 2015-09-20
          • 1970-01-01
          • 2020-09-28
          • 1970-01-01
          • 2021-02-09
          • 2017-03-31
          • 1970-01-01
          • 2012-06-05
          相关资源
          最近更新 更多