2017-04-24 76 views
0

我有HTML,看起來像這樣如何搜索和Vim中與子匹配替換值

<form> 
    <input id="firstname" value=""/> 
    <input id="lastname" value=""/> 
    <input id="email" value=""/> 
</form> 

我要添加名稱=下面的「{ID名}」到每個輸入字段(參見示例代碼)

<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)搜索,從第一次報價搜索到最後報價。它應該從第一個報價到下一個報價。

enter image description here

2.)submatch(0)正在搜索的全部結果。我如何將它隔離到只有id="{value}"之間的值?

我遇到過這個問題很多,搞清楚這個vim命令可以幫助我在將來爲我節省很多時間。主要將搜索結果拆分爲submatch()我也看到有人用堆棧使用\1 \2而不是submatch()來存儲結果,這種方法是否更好?

任何幫助將不勝感激!謝謝!

回答

2

我首先想到的是,這個問題將是對the Vim Stack Exchange更合適...

但我會在這裏回答也無妨


您所遇到的第一個問題是稱爲貪婪。基本思想是*量化是貪婪,所以它試圖匹配儘可能多的文字。更深入的解釋可以是found here

要解決這個問題,您可以簡單地使用*的非貪婪等價物,即\{-}。由於這是非貪婪的,它會嘗試儘可能少地匹配文本。例如,看這樣的文字:

"hello", "world", "test" 

運行

:s/".*" 

將刪除一切,但

:s/".\{-}" 

只會刪除"hello"

要解決你的第二個問題,你我們需要考慮捕捉羣體。基本上,無論你括在圓括號中的什麼都將被放入組1中,那麼下一對括號將會是組2,依此類推。默認情況下,整個匹配模式被放置在組0中。

我也推薦而不是使用eval運算符,即\=。這使得事情變得冗長。你舉的例子是完全等同於

:%s/id=".*"/\0/g 

由於\0指0組,\1意味着1組等

所以,你可以這樣做:

:%s/id="\(.\{-}\)"/\0 name="\1"/g 

現在,只需幾個小的提示:

  1. 您可以使用&\0的地方。

  2. 使用\v打開魔術性這樣可以去掉一些反斜槓(見:help /\v

  3. 既然你只需要更換每行一個比賽,把/g末是不必要的。

把這個都在一起,我會建議以下的正則表達式:

:%s/\vid=(.{-})/& name="\1" 
+0

我不得不使用\ =以變化的魔法':%S =符\ v \ ZS(」 { - } 「),&name =&' – SergioAraujo