不知道我是否正确理解了你的问题。
使用该功能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
因为\zs
and\ze
matchstr(str, match)
返回match
instr
matchstr(@w, '\v"\zs[^"]+\ze"')
获取行间"
和"
行间的字符(使用 reg w
)
- ...并用它来替换匹配的
test
/g
[<almost any characters>_test]
为该行中所有出现的