我需要将所有 <filename>...</filename> 标签内的 / 字符替换为 \。
文件中有大约 2,000 个这些标签,我只需要替换标签内的 / 字符。
我该怎么做?
编辑:鉴于新的信息,下面的替换可能会起作用:
:%s/<filename>\zs.\{-}\ze<\/filename>/\=substitute(submatch(0), '\/', '\', 'g')/
解释:
%s
:替换整个文件/<filename>
:匹配开始的模式和静态文本\zs
:匹配文本的开始.\{-}
:任意字符,非贪婪\ze
:匹配文本的结束<\/filename>/
:目标标记和模式的结束\=
:将替换结果作为vim表达式进行求值substitute(submatch(0), '\/', '\', 'g')/
: 将匹配文本中所有的/
替换为\
原始回答:
我假设你是指XML风格的标签。我会首先视觉选择要操作的区域,然后使用\%V
正则表达式原子只在该选择区域上操作。
vit:s!\%V/!\\!g
这应该可以解决问题。请注意,在按下:
时,vim将自动为视觉选择添加一个范围,实际的替换命令看起来像:
:'<,'>s!\%V/!\\!g
假设我们可以假定标签位于单独的一行,那么解决方法如下:
注意 输入^M
时,请使用C-vC-m(在Windows上请使用C-qC-m)
:g/<filename>/norm! /filename>/e^Mvity:let @"=substitute(@", '/', '\\', "g")^Mgvp
嗯,按照兰迪提供的提示,在模式中使用 \%V 使得它更简单:
:g/<filename>/norm! /filename>/e^Mvit:s#\%V/#\\#g^M
我测试过了,哇。现在我来解释一下,请稍等。
:g/<filename>/
- 对于每一行包含 <filename>
的内容norm!
- 执行普通命令(忽略映射)/filename/e
Enter 跳转到开放标签的结尾vit
- 在可视模式下选择该标签内的文本:s#\%V/#\\#g
Enter - 在可视选区上执行替换操作(将 \
替换为 /
)VIM有一个陡峭的学习曲线,正则表达式也是如此。我相信这个命令会做到这一点。你必须用'\'转义每个字符。
:%s/\//\\/g