【问题标题】:Help with back reference regex in Vim帮助 Vim 中的反向引用正则表达式
【发布时间】:2011-09-22 23:27:45
【问题描述】:

我正在尝试在 vi 中编写一个正则表达式来匹配任何空格字符后跟任何数字。然后,在每次匹配时,在空格和数字之间插入一个美元符号。这是一个例子:

A1234 12 14 B1234
B1256 A2 14 C1245
C1234 34 D1 1234K

正确的正则表达式会产生这样的结果:

A1234 $12 $14 B1234
B1256 A2 14 C1245
C1234 $34 D1 $1234K

我意识到我需要使用反向引用,但我似乎无法编写正确的正则表达式。这是我的尝试:

:'<,'>/(\s\d)/\s\1\$/g

另外,我关闭了 Vim 的默认正则表达式模式 (vnoremap / /\v)。

感谢您的帮助。

【问题讨论】:

  • 为什么正确结果示例的第二行中的数字14 前面没有$

标签: regex vim backreference


【解决方案1】:

您需要转义括号以使它们作为分组而不是文本中的实际匹配项,并且转义$。像这样:

:%s/\(\s\)\(\d\)/\1$\2/g

这在 vim 中对我有用(使用标准魔法设置)。

编辑:刚刚意识到您的非标准正则表达式设置会导致您“反过来”转义。但是,我认为诀窍仍然是使用两组。使用您的设置,这应该可以工作:

:%s/(\s)(\d)/\1$\2/g

【讨论】:

  • 即使在“魔术”模式下,也无需转义$ 登录:substitute 命令的替换部分。
【解决方案2】:

使用反向引用并非不可避免。可以制作一个匹配的模式 空白字符和数字之间的零宽度文本,并将其替换 带有$ 符号的空区间。

:'<,'>s/\s\zs\ze\d/$/g

(有关原子改变 比赛的边界。)

【讨论】:

  • @sidyll:“正确”?是否有一些我遗漏的标准文件?
  • 对不起@Johnsyweb,我不想听起来这么糟糕。不是因为它被记录在案,而是因为它使用了大部分仅在 Vim 中看到的功能(\ze 和 \zs),从而更简洁。
  • @sidyll:谢谢,我也有同感!不过,有时人们更看重诡计而不是优雅。 (喜欢这里或that question。)
【解决方案3】:

我的第一个想法是:

:%s/(\b\d)/$\1/g

\b 用于单词边界。但事实证明,\b 并不意味着 Vim 正则表达式中的单词边界,而是 \&lt;\&gt; 表示单词的开头和结尾。所以正确的答案是:

:%s/\(\<\d\)/$\1/g

(确保转义捕获括号。)

很抱歉我的修正来得太晚了。

【讨论】:

  • 我正在尝试在视觉块上进行替换,所以我做了:'&lt;,'&gt;s/(\s\d)/$\1/g,但它没有用。 \b\s 出现 Pattern not found 错误。
  • 对不起,我现在没有机会测试它,我稍后会研究它。
  • IIRC \b 是退格,而不是单词边界。
  • 嗯 ...它是 sed 正则表达式的单词边界,但显然不是 Vim。
  • '标准的伟大之处......'
【解决方案4】:

不确定确切的 vim 语法,但 regEx 语法应该是这样的:

search expr - "(\s)([\d])"
replacement expr - "\1 $\2"

类似:

/(\s)([\d])/\1 $\2/g

【讨论】:

    【解决方案5】:

    这将为您完成工作(不使用组):

    :%s/\s\@<=\d\@=/$/g
    

    解释:

    • %:每一行……
    • s:替补……
    • /:模式开始
    • \s:空格
    • \@&lt;=: 后面匹配(零宽度)
    • \d:数字
    • \@=:需要匹配(零宽度)
    • /:模式结束,替换开始
    • $:你要的!
    • /:替换结束
    • g:替换该行中的所有匹配项。

    【讨论】:

      猜你喜欢
      • 2012-03-01
      • 1970-01-01
      • 2017-01-15
      • 1970-01-01
      • 1970-01-01
      • 2011-06-10
      相关资源
      最近更新 更多