我每天都在使用vim来操作文本和编写代码。但是,每次我必须执行任何替换,或做任何类型的正则表达式工作,它都会让我发疯,我必须切换到崇高。我想知道,解决这个问题的正确方法是什么:
<img src="whatever.png"/>
<img src="x.png"/>
到
<img src="<%= image_path("whatever.png") %>"/>
<img src="<%= image_path("x.png") %>"/>
在崇高中,我可以将其用作搜索的正则表达式:src="(.*?.png)"
,并将此作为替换的正则表达式:src="<%= asset_path("\1") %>"
。在vim中,如果我这样做::%s/\vsrc="(.*?.png)/src="<%= asset_path("\1") %>"/g
我得到:
E62: Nested ?
E476: Invalid command
我做得不对?
答案 0 :(得分:4)
正如@nhahtdh所言,Vim的正则表达方言使用\{-}
作为非贪婪量词。如果您使用非常神奇的旗帜,它只是{-}
。所以你的命令变成了:
:%s/\vsrc="(.{-}.png)/src="<%= asset_path("\1") %>"/g
但是你没有逃避.
中的.png
所以:
:%s/\vsrc="(.{-}\.png)/src="<%= asset_path("\1") %>"/g
但我们仍然可以做得更好!通过使用\zs
和\ze
,我们可以避免重新输入src="
位。 \zs
和\ze
标记将进行替换的匹配的开始和结束。
:%s/\vsrc="\zs(.\{-}\.png)"/<%= image_path("\1") %>"/g
但是我们仍然没有完成,因为如果我们谨慎选择放置\zs
和\ze
的位置,我们可以更进一步,那么我们可以在替换中使用vim的&
。它就像Perl的正则表达式语法中的\0
。现在我们不需要任何捕获组来消除对魔法旗的需要。
:%s/src="\zs.\{-}\.png\ze"/<%= image_path("&") %>/g
如需更多帮助,请参阅以下文档:
:h /\zs
:h /\{-
:h s/\&
答案 1 :(得分:3)
根据this website,vim中的lazy量词的语法与Perl-like regex中使用的语法不同。
让我引用网站:
*/\{-* \{-n,m} matches n to m of the preceding atom, as few as possible \{-n} matches n of the preceding atom \{-n,} matches at least n of the preceding atom, as few as possible \{-,m} matches 0 to m of the preceding atom, as few as possible \{-} matches 0 or more of the preceding atom, as few as possible {Vi does not have any of these} n and m are positive decimal numbers or zero *non-greedy* If a "-" appears immediately after the "{", then a shortest match first algorithm is used (see example below). In particular, "\{-}" is the same as "*" but uses the shortest match first algorithm.
答案 2 :(得分:2)
:%s/"\(.*\)"/"<%= image_path("\1") %>"/g
双引号是主要模式。我们想要捕获的所有内容都会被投放到一个组\( \)
中,以便我们以后可以通过\1
与之关联。
如果您使用非常神奇的,则必须转义=
,因此\vsrc\=(.*).png"
。所以用你的方式答案是:
:%s/\vsrc\="(.*\.png)"/src="<%= image_path("\1") %>"/g
很容易看出你是:set hlsearch
然后再玩/
。 :)