2013-02-15 32 views
1

我怎麼能實現在VIM以下VIM每行替換在同一行基於另一個字一個字

substitute/regex_this_word/regex_with_another_word_from_the_same_line 

select "ali" as name where _placeholder = _placeholder 
union 
select "sam" as name where _placeholder = _placeholder 

應用

:%s/_placeholder/anythin_between_quotation/ 

後變成

select "ali" as name where ali = ali 
union 
select "sam" as name where sam = sam 
e.g2

select id, "_placeholder" as vul members_repeater/vul/none 

施加後

:%s/_placehold/\=something_like_regexp(getline('.'),'regexp_pattern_to_select_everthing_after_/vul/") 

變得

select id, "none" as vul members_repeater/vul/none 

感謝

+1

每行只有一個報價部分? – Kent 2013-02-15 15:59:58

+0

好吧,我只是把它作爲一個例子,最終它是一個正則表達式,對吧? – Ali 2013-02-15 16:06:58

回答

4
:%s/_placeholder/\=split(getline("."),'"')[1]/g 

這部作品在這種情況下:只有

  • 一個報價部分(替換)中的每一行
  • 報價部分可能是任何地方在這一行
例如:

select "ali" as name where _placeholder = _placeholder 
union 
select "sam" as name where _placeholder = _placeholder 
select _placeholder where _placeholder = _placeholder "foo" 
select _placeholder where "bar", _placeholder = _placeholder 

select "ali" as name where ali = ali 
union 
select "sam" as name where sam = sam 
select foo where foo = foo "foo" 
select bar where "bar", bar = bar 

編輯

\=split(getline("."),'"')[1] 
| |  | 
| |  +--- get current line text 
| | 
| +------ split the line with " as separator, pick the middle part ([1]) 
| 
| 
+---- using expression replacement 

新的編輯

這樣你就可以重新使用的老套路:

:%s#_placeholder#\=split(split(getline("."),"vul/")[1]," ")[0]#g 

這個只需要一個vul/在您的線路,但也有可能是關鍵字(與空間分隔符)後的文本喜歡的東西:

select id, "_placeholder" as vul members_repeater/vul/none trashtrash 

select id, "none" as vul members_repeater/vul/none trashtrash 

看看這個例子:

enter image description here

+0

哇,非常巧妙地使用右側:) – Tim 2013-02-15 16:11:54

+0

它的工作原理,但你能解釋更多它是如何工作的? – Ali 2013-02-15 16:12:32

+0

還有一件事,如果每行中有多個報價部分,該怎麼辦?我知道我很挑剔,但我們在這裏學習,對吧? :) – Ali 2013-02-15 16:15:20

1

特別是對於這些行,這將是

s/^\(.*\)"\([^"]*\)"\(.*\)_placeholder\ = _placeholder/\1"\2"\3\2 = \2/ 

說明:表達式匹配對\(\)之間是\ 1捕獲,\ 2等。因此,在這裏進行的一種方式是捕獲一切都交給_placeholder,並有把它放回去。有一點難以理解,誠然。

該解決方案假定每行上只有一個雙引號的表達式。

+0

mmmm,你可以分解成不同的線條,並解釋每一行,這是我很難讀懂它, 謝謝 – Ali 2013-02-15 16:09:28

+0

它沒有工作:( 'E486:模式未找到:^ \(。* \ ) 「\([^」] * \)「\(。* \)_ placeholder \ = _placeholder' – Ali 2013-02-15 16:11:43

+1

您沒有複製反斜槓。無論如何,很高興肯特的解決方案爲你工作。 – 2013-02-15 17:51:44

1

你可以很容易地使用sed,如果知道的話,它允許您使用正則表達式的擴展:

example_with_no_link.txt:

from django.utils import unittest 
from django.core import management 
from app import subapp 

Vim命令:

:%! sed -re "/django/ s/from (.*) import (.*)/from \2 import \1/" 

此命令執行以下的事情:
1. :%!:將所有行放入標準輸出中
2. sed -re "/django/:如果行中有'django'
3. s/from (.*) import (.*)/from \2 import \1/:括號內的反轉模式

在sed中,您用括號將搜索到的單詞與\n一起寫出來。
輸出重定向到vim。

+0

請解釋:) – Ali 2013-02-15 16:59:17

+0

'vim'得到了'ed'的命令,但它們被改進了'sed'。 – Zulu 2013-02-15 17:08:04

+1

@Zulu我沒有看到在你的例子中使用sed的優勢。 sed -r的擴展正則表達式不是賣點,vim regex比擴展正則表達式強大得多。 vim:s也支持\ 1,\ 2。但如果外部cmd可以輕鬆快速地解決問題,那麼這是一條可行的途徑。 – Kent 2013-02-15 17:30:57

相關問題