2

我正在尝试在 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)。

谢谢您的帮助。

4

5 回答 5

9

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

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

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

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

:%s/(\s)(\d)/\1$\2/g
于 2011-09-23T00:58:11.387 回答
5

使用反向引用并非不可避免。可以创建一个模式来匹配空白字符和数字之间的零宽度文本,并用$符号替换那个空间隔。

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

(有关改变匹配边界的原子的详细信息,请参阅:help /\zs:help /\ze。)

于 2011-09-23T01:31:55.157 回答
1

我的第一个想法是:

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

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

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

(确保转义捕获括号。)

对不起,我的修正来得太晚了。

于 2011-09-22T23:32:01.580 回答
0

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

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

解释:

  • %: 在每一行...
  • s: 代替...
  • /: 模式的开始
  • \s: 空白
  • \@<=: 匹配后面(零宽度)
  • \d: 数字
  • \@=:需要匹配(零宽度)
  • /:模式结束,替换开始
  • $: 你问的!
  • /: 更换结束
  • g:替换该行中的所有匹配项。
于 2011-09-23T01:24:49.290 回答
0

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

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

所以像:

/(\s)([\d])/\1 $\2/g
于 2011-09-22T23:34:00.413 回答