Joh*_*Doe 2 linux vi vim terminal
我的HTML看起来像这样
<form>
<input id="firstname" value=""/>
<input id="lastname" value=""/>
<input id="email" value=""/>
</form>
Run Code Online (Sandbox Code Playgroud)
我想在每个输入字段中添加name ="{id-name}"(参见下面的示例代码)
<form>
<input id="firstname" name="firstname" value=""/>
<input id="lastname" name="lastname" value=""/>
<input id="email" name="email" value=""/>
</form>
Run Code Online (Sandbox Code Playgroud)
我怎么能用Vim做到这一点?
我在尝试
%s/id=".*"/\=submatch(0)/g
Run Code Online (Sandbox Code Playgroud)
这导致了两个问题:
1)搜索,从第一个报价搜索到最后一个报价.它应该从第一个引号搜索到下一个引用.
2.)submatch(0)正在取得搜索的全部结果.我怎样才能将它隔离到只有两者之间的值id="{value}"?
我经常遇到这个问题,弄清楚这个vim命令可以帮助我节省很多时间.主要是将搜索结果拆分为submatch()我还看到人们在堆栈上使用\1 \2而不是submatch()存储结果,这种方法更好吗?
任何帮助将不胜感激!谢谢!
我的第一个想法是这个问题在Vim Stack Exchange上更合适......
但无论如何我会在这里回答
您遇到的第一个问题称为贪婪.基本思想是*量化是贪婪的,所以它试图尽可能多地匹配文本.可以在此处找到更深入的解释.
要解决这个问题,你可以简单地使用非贪婪的等价物*,即\{-}.由于这不是贪婪的,它会尝试尽可能少地匹配文本.例如,看看这个文字:
"hello", "world", "test"
Run Code Online (Sandbox Code Playgroud)
运行
:s/".*"
Run Code Online (Sandbox Code Playgroud)
会删除所有东西,但是
:s/".\{-}"
Run Code Online (Sandbox Code Playgroud)
只会删除 "hello"
要解决第二个问题,您需要研究捕获组.基本上,括号中的任何内容都将被放入第1组,然后下一对括号将是第2组,依此类推.默认情况下,整个匹配的模式放在组0中.
我也建议不要使用eval运算符\=.这使事情变得不必要地冗长.你的例子完全等同于
:%s/id=".*"/\0/g
Run Code Online (Sandbox Code Playgroud)
由于\0意味着组0,\1意味着组1等.
所以你可以这样做:
:%s/id="\(.\{-}\)"/\0 name="\1"/g
Run Code Online (Sandbox Code Playgroud)
现在,还有一些小技巧:
你可以&代替使用\0.
使用\v开启魔法,这样你就可以删除一些反斜杠(参见参考资料:help /\v)
由于您只想每行替换一个匹配,/g因此不需要放在最后.
把这一切放在一起,我会推荐以下正则表达式:
:%s/\vid=(.{-})/& name="\1"
Run Code Online (Sandbox Code Playgroud)