如何逃避正则表达式\([''"]\)\(.\{-}\)\1
和*test
在以下功能
:%s/.*/\=substitute(submatch(0),"\([''"]\)\(.\{-}\)\1","*test","g")/
第一个正则表达式匹配每行中引号之间的任何内容,并将其替换为与同一行中的第二个正则表达式匹配的内容
感谢, 最好
编辑: 例如:
select "foo" as subject from table where [subject_test]=true
union
select "bar" as subject from table where [subject_test]=true
应该成为
select "foo" as subject from table where [subject_foo]=true
union
select "bar" as subject from table where [subject_bar]=true
答案 0 :(得分:2)
不知道我是否理解你的问题。
使用函数substitute()
时,模式的其他规则比使用例如:s///
。
见::h substitute()
部分内容来自:
...
但与{pat}的匹配总是像“魔法”一样完成。选项是 设置和' cpoptions'是空的(使脚本可移植)。 '忽略大小写'仍然相关。 '智能大小写'不使用。
...
请注意,{sub}中的某些代码具有特殊含义 |子取代,特别|。例如,用" \ 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")
棘手的部分是在函数substitute()中使用模式作为字符串,这不是通常在命令行中使用模式的情况。 :s///
。
编辑(再次由于OP的评论):
不能说我理解你的例子的用法,但我无法用你问题中的ex命令来解决它(我试图在VIM上学习VIM)同一时间)。这是一个有效的命令,并给出你想要的结果,但同样,我不明白它的用途。
但似乎问题是学习如何在字符串中逃避正则表达式
如果"字符串"总是在替换之前(并且只为每个"")替换一个test
:
:%s/\v"([^"]+)".*_\zstest/\1/g
<强>解释强>
\zs
=开始匹配,\v
=使用&#34;非常神奇&#34; "([^"]+)"
&#34;匹配&#34;除"
和"
之间的"
(最少1)之外的所有字符
(&#34;真正的比赛&#34;还没有开始,但是括号中的匹配仍然是1号子匹配).*
所有字符到下一个表达式:_\zstest
&#34;匹配&#34; _test
,但是\zs
使得#34;真正的匹配&#34;在此之后开始,因此只有test
将被替换。/\1/
替换为子匹配编号1 已更改这不安全&#34;,我添加了一些更长的匹配(来自 @Kent &#39;答案),并确保只处理"<any characters>"
的行
如果&#34;字符串&#34;可以在替代之前或之后
:g/\v"[^"]+"/y w | s/\v\[\w*_\zstest\ze\]/\=matchstr(@w, '\v"\zs[^"]+\ze"')/g
<强>解释强>
\v
=&#34;非常神奇&#34; g/\v"[^"]+"
使用包含"<some text>"
/y w
猛烈地注册到reg。 w
(而不是使用getline())|
再增加一个命令\zs
=开始匹配,\ze
=结束匹配(比使用预测更快等)。\w
与使用[0-9A-Za-z_]
\[\w*_\zstest\ze\]
&#34;匹配&#34; [<almost any characters>_test]
,但真正的匹配&#34;由于test
和\zs
\ze
matchstr(str, match)
返回match
str
matchstr(@w, '\v"\zs[^"]+\ze"')
从该行获取"
和"
之间的字符(使用reg w
)test
/g
为行[<almost any characters>_test]
执行此操作
答案 1 :(得分:1)
这对你好吗?
%s/\[.\{-}_\zstest\ze\]/\=split(getline('.'), '"')[1]/
这也适用(使用你的例子),并且直截了当:
%s/\[subject_test\]/\="[subject_".split(getline("."),'"')[1]."]"/
答案 2 :(得分:0)
在VimL中,单引号字符串不插入反斜杠,而双引号字符串则执行。
因此,请注意:echo '\'
和:echo "\\"
之间的区别。在你的例子中,你使用双引号,因为你没有关闭魔法,你有很多逃避做。见:help magic
...因为我发现了\v
,所以人们告诉我,我会更愉快。
答案 3 :(得分:0)
要转义在替代函数中使用的字符,我使用escape()
Escape the characters in {chars} that occur in {string} with a backslash.
Example:
:echo escape('c:\program files\vim', ' \')
Results in:
c:\\program\ files\\vim
例如,您可以使用escape('\([''"]\)\(.\{-}\)\1','\')
这将扩展为:\\(['"]\\)\\(.\\{-}\\)\\1