代码之家  ›  专栏  ›  技术社区  ›  Sabuncu

Vim中的正则表达式在第一次传球中错过了两场比赛中的第二场,需要第二次传球

  •  1
  • Sabuncu  · 技术社区  · 7 年前

    在Windows上使用Vim 7.4,我试图从C文件的代码中删除括号前后不必要的空格;例子:

    copyFunc ( copyLength, sizeof ( type ) );
    

    以下模式删除右括号前的空格:

    :%s/\(\S\) )/\1)/g
    

    我惊讶地发现,上面的模式删除了紧随其后的第一个空格 type 在上一行中,但跳过了下一行,在最后两个连续的右括号之间 ) ) 在这条线的尽头。

    copyFunc ( copyLength, sizeof ( type) );
                                         ^
                                         Not removed on first pass
    

    请注意,我不是在寻找解决方案。相反,我感兴趣的是了解这种正则表达式行为的原因。

    1 回复  |  直到 7 年前
        1
  •  3
  •   Ingo Karkat    7 年前

    为了避免无休止的递归(因为它通常是有意义的), :substitute /g 标志仅考虑 文本尚未匹配 对于一行文本的进一步迭代。

    你的文字 ) 按照你的模式 \(\S\) ) 匹配右括号;因此,它不能再次匹配(这次为 \S )在进一步的迭代中。

    解决这个问题的一种方法是结束比赛 之前 右括号。这可以通过 积极展望未来 ,或更容易(在Vim中)以结束匹配 \ze :

    :s/\(\S\) \ze)/\1/g