2014-02-07 121 views
3

我有文本在某些行包含正確的字符串轉義雙引號,有些不是 象下面這樣:取代方式逃避VIM引號

bla1 "aaa"bbb"ccc" bla1 
bla2 "aaa\"bbb\"ccc" bla2 

取代後的結果應該是

bla1 "aaa\"bbb\"ccc" bla1 
bla2 "aaa\"bbb\"ccc" bla2 

但不是:

bla1 "aaa\"bbb\"ccc" bla1 
bla2 "aaa\\"bbb\\"ccc" bla2 

換句話說,它應該逃脫在線路雙引號,他們都沒有逃過 ,不碰這是已經正確地轉義

行到目前爲止,我得到了第二次的結果與此

%s:\(\s".\+\)\(".\+\)\(".\+"\s\):\1\\\2\\\3:g 

然後,我已經嘗試了負回顧後告訴發動機不匹配 如果有引號

(?<!\) which in vim should be something like @<!\ 

%s:\(\s".\+\)\@<!\\\(".\+\)@<!\\\(".\+"\s\):\1\\\2\\\3:g 

前一個反斜槓但是我想我有一個小小的失落。

注:
有每行 只有一個這樣的字符串,長度爲雙引號括起來,並且可以包含內部雙引號 - 只是這裏面的人都不應逃脫

回答

2

:現在只適用於那些尚未包含行轉義的引號。 (這也導致更容易的正則表達式的命令的所有部分)

:%s/"\zs.*\ze"/\=substitute(submatch(0), '\\\@<!"', '\\"', 'g') 

說明:

  1. :%s/"\zs.*\ze"匹配第一個和最後一個引號之間樣樣在行。我們使用貪婪.*來做到這一點。 \zs表示比賽開始,\ze表示比賽結束。
  2. 之後,我們可以通過將\=添加到替換開始,將匹配傳遞給第二個替換命令。這意味着它後面的表達式的結果將是替換字符串。

    substitute(submatch(0), '\\\@<!"', '\\"', 'g') 
    

    submatch(0)是引號之間的所有內容。然後我們用\"替換所有沒有斜槓的報價(\\\@<!")。

乘坐戰利品在:h sub-replace-expression:h /\zs:h /\ze


例輸入:

bla1  "aaa"bbb"ccc"  bla1 
bla2  "aaa\"bbb\"ccc" bla2 
bla\bla3 "aaa"bbb"ccc"  bla3 
blabla4 "aaa"bbb" "BBB"ccc" bla4  
bla\bla5 "aaa"bbb" "BBB"ccc" bla5 
bla\bla5 "aaa"bbb""BBB"ccc" bla5 

輸出示例:

bla1  "aaa\"bbb\"ccc"  bla1 
bla2  "aaa\"bbb\"ccc" bla2 
bla\bla3 "aaa\"bbb\"ccc"  bla3 
blabla4 "aaa\"bbb\" \"BBB\"ccc" bla4  
bla\bla5 "aaa\"bbb\" \"BBB\"ccc" bla5 
bla\bla5 "aaa\"bbb\"\"BBB\"ccc" bla5 
+0

嗨這個答案比Jeff的更好我修改了輸入輸出數據以表明它可以工作,即使在一個字符串中有多個引號我也會接受它只有一個小例子它不起作用因爲我會把它想 例如: 喇嘛\ bla5 「AAA」 BBB 「」 BBB 「CCC」 bla5 成爲 喇嘛\ bla5 「AAA \」 BBB \ 「」 BBB \ 「CCC」 bla5 的情況是,如果有兩個雙引號「」 也許你知道如何使它適用於這種情況 – szydan

+0

對不起,我也按下輸入早現在評論應該沒問題 – szydan

+0

@szydan我改變了第二個替代命令中的正則表達式,以便使用負面看起來後面。當兩個引號相鄰時,這是有效的。 – FDinoff

0
:%s/\([^ \\]\)"\([^ ]\)/\1\\"\2/g 

此發現引號不在斜線或空格前面,後面沒有空格。

+0

凱文這並沒有工作 - 我已經添加了一個注意問題 重要的是我只想逃避雙引號內的雙引號,而不是所有的雙引號 – szydan

0

這可能會實現:

%s/\([^\\]\)\("\)/\1\\\2/g 
+0

首先,你不需要捕獲引號,你知道' \ 2'總是會是一個,其次,這也會得到外部的引號。 – Kevin

1

你可以只堅持全球反到你已經寫命令之一。既然你說只有1每行字符串,可以替代鏈命令來獲取你想要的結果

:v/\\"/s:\(\s".\+\)\(".\+\)\(".\+"\s\):\1\\\2\\\3:g 
+0

似乎工作。請你只是解釋一下這個第一部分v/\\/ – szydan

+0

看看':h global'。使用'v'而不是'g'將命令應用於與模式不匹配的行,在這種情況下,該行只是一個反斜槓。 – Jeff

+0

謝謝不錯的訣竅,但在這種情況下會失敗 bla \ bla3「aaa」bbb「ccc」bla3在實際字符串之前有blabla的反斜槓 – szydan