我的HTML看起来像这样
<form>
<input id="firstname" value=""/>
<input id="lastname" value=""/>
<input id="email" value=""/>
</form>
我想在每个输入字段中添加name =“{id-name}”(参见下面的示例代码)
<form>
<input id="firstname" name="firstname" value=""/>
<input id="lastname" name="lastname" value=""/>
<input id="email" name="email" value=""/>
</form>
我怎么能用Vim做到这一点?
我正在尝试
%s/id=".*"/\=submatch(0)/g
这导致了两个问题:
1)搜索,从第一个报价到最后一个报价进行搜索。它应该从第一个引号搜索到下一个引用。
2。)submatch(0)
正在取得搜索的全部结果。如何将其仅隔离id="{value}"
?
我经常遇到这个问题,弄清楚这个vim命令可以帮助我节省很多时间。主要是将搜索结果拆分为submatch()
我还看到堆叠中的人使用\1 \2
代替submatch()
来存储结果,这种方法更好吗?
任何帮助将不胜感激!谢谢!
答案 0 :(得分:5)
我的第一个想法是,这个问题更适合the Vim Stack Exchange ...
但我会在这里回答
您遇到的第一个问题称为贪婪。基本思想是*
量化是贪婪,因此它尝试匹配尽可能多的文本。更深入的解释可以是found here。
要解决此问题,您只需使用*
的非贪婪等效项,即\{-}
。由于这不是贪婪的,它会尝试尽可能少地匹配文本。例如,看看这个文本:
"hello", "world", "test"
运行
:s/".*"
将删除所有内容,但
:s/".\{-}"
只会移除"hello"
要解决第二个问题,您需要查看捕获组。基本上,括号中的任何内容都将被放入第1组,然后下一对括号将是第2组,依此类推。默认情况下,整个匹配的模式放在组0中。
我还建议使用eval运算符 not ,即\=
。这使事情变得不必要地冗长。您的示例完全等同于
:%s/id=".*"/\0/g
由于\0
表示组0,\1
表示组1等,
所以你可以这样做:
:%s/id="\(.\{-}\)"/\0 name="\1"/g
现在,还有一些小技巧:
您可以使用&
代替\0
。
使用\v
启用魔力,以便删除一些反斜杠(请参阅:help /\v
)
由于您只想每行替换一个匹配项,因此不需要将/g
放在最后。
总而言之,我建议使用以下正则表达式:
:%s/\vid=(.{-})/& name="\1"