不知道我是否正确理解了你的问题。
使用该功能substitute()时,除了使用 eg 时,还有其他模式规则:s///。
看到这个::h 替代()
其中的一些部分:
...
但是与 {pat} 的匹配总是像设置了 'magic' 选项并且 'cpoptions' 为空(使脚本可移植)一样。'ignorecase' 仍然是相关的。不使用'smartcase'。
...
请注意,{sub} 中的某些代码具有特殊含义|sub-replace-special|。例如,要将某些内容替换为“\n”(两个字符),请使用“\\n”或“\n”。
不清楚如何使用特殊的正则表达式代码,但如果您对模式字符串使用双引号,它们应该与双反斜杠一起使用,"\\"表示字符\,并且与'\'. 这些在使用函数替代()
时应该是等价的:
而我最喜欢的是使用(“非常神奇”),所以我不必反斜杠一些正则表达式:
'\([a-z]\)'
"\\([a-z]\\)"
\v
"\\v([a-z])"
你的例子应该是(我没有考虑你的模式是否正确)
substitute(submatch(0), '\v([''"])(.{-})\1', "*test", "g")
Or:
substitute(submatch(0), "\\v(['\"])(.{-})\\1", "*test", "g")
棘手的部分是,在函数替代()中,您将模式用作字符串,这不是在例如命令行中通常使用模式时的情况:s///。
编辑(再次由于 OP 的评论):
不能说我理解你的例子的使用,但我忍不住尝试用你问题中的 ex 命令修复它(我正在尝试同时了解VIM)。这是一个有效的命令,并给出了你想要的结果,但同样,我不明白它的用途是什么。
但似乎问题真的是要学习如何在字符串中转义正则表达式。
如果“字符串”总是在要替换的内容之前(并且test每个“”只替换一个):
:%s/\v"([^"]+)".*_\zstest/\1/g
解释
\zs=开始比赛,\v=使用“非常神奇”
"([^"]+)"“匹配”除"(最少 1 个)和之间"的所有字符( "
“真正的匹配”尚未开始,但括号中的匹配将作为子匹配编号 1)
.*直到下一个表达式的所有字符:
_\zstest"match" _test,但\zs在此之后开始“真正的匹配”,所以只有test那个会被替换。
/\1/替换为子匹配号 1
已更改这不是“安全的”,我添加了一些更长的匹配项(来自@Kent的回答),并确保仅处理了已"<any characters>"处理的行。
如果“字符串”可以在替换之前或之后
:g/\v"[^"]+"/y w | s/\v\[\w*_\zstest\ze\]/\=matchstr(@w, '\v"\zs[^"]+\ze"')/g
解释
\v=“非常神奇”
g/\v"[^"]+"使用具有"<some text>"
/y w将线路拉到 reg。w(而不是使用 getline())
|再有一个命令
\zs= 开始匹配,\ze= 结束匹配(比使用前瞻等更快)
\w与使用相同[0-9A-Za-z_]
\[\w*_\zstest\ze\]"match" [<almost any characters>_test],但要替换的“真正匹配”是test因为\zsand\ze
matchstr(str, match)返回matchinstr
matchstr(@w, '\v"\zs[^"]+\ze"')获取行间"和"行间的字符(使用 reg w)
- ...并用它来替换匹配的
test
/g[<almost any characters>_test]为该行中所有出现的