2016-11-01 68 views
2

我需要對vim中的正則表達式和文本操作進行此練習。vim:替換特定字符,但僅在第n次出現後

所以我對最得分的足球運動員在歷史上的這一文件,與50個條目看起來像這樣:

1 Cristiano Ronaldo Portugal 88 121 0.73 03 Manchester United Real Madrid

的字段之間的空格被標籤(\ t)的

的字段中的每一個都對不同的類別作出響應:等等...... 這最後一個字段包含一個或多個玩家玩過的俱樂部。(所以不是固定數量的俱樂部)

問題:re將所有選項卡放在一個';'中,除了最後一個字段,俱樂部需要用','分隔。

所以我想:我只是用逗號替換它們,然後用分號替換前7個逗號。但是,你是怎麼做的?從正則表達式到vim命令的所有內容都是允許的。

第一部分很容易::2,$s/\t/,/g 但第二部分,我似乎無法弄清楚。

任何幫助將不勝感激。

感謝,芝諾

+0

是否必須是一個正則表達式的解決方案,或將使用的其它Vim特色(全局命令,普通命令,宏等)的一些組合來好嗎? – DJMcMayhem

+0

是的,命令是允許的,我只是'假設'它會與正則表達式,我會相應地改變標題 –

回答

2

這個答案是類似於@ Amadan的,但它利用提供了表達的能力作爲替換字符串實際做改變第一組選項卡,以分號的困難位:

%s/\v(.{-}\t){7}/\=substitute(submatch('0'), '\t', ';', 'g')/|%s/\t/,/g 

分解這是一組三個替代命令。前兩個是一個sub-replace-expression拼湊起來:

%s/\v(.{-}\t){7}/\=substitute(submatch('0'), '\t', ';', 'g')/ 

這樣做是找到任何字符後按Tab的整整7 occurrances({7}),在非貪婪的方式。 ((.{-}\t))。然後我們用替代表達式(\=substitute(...))的結果替換整個比賽(submatch(0))。替代表達式只是比較簡單,因爲它只是將所有制表符轉換爲分號。

最後一個替代品只是將行上的其他選項卡更改爲逗號。

:help sub-replace-expression

+0

這似乎是可行的!只有一個問題:我說得對,點後面應該有一個星號? –

+0

不會。* *是一個貪婪的匹配,並會吃掉所有東西,直到最後一個選項卡。 '{ - }'是非貪婪的版本。在這種情況下,由於'{7}'並不重要,但總的來說,我發現最好使用非貪婪的匹配,除非你真的想要貪婪。 –

+0

哦,好的,謝謝!將接受這個答案,而不是我的,因爲我認爲它比我的解決方案更好。 –

0

這裏是你可以做的一種方式:

:let @q=":s/\t/;\<cr>" 
:2,$norm [email protected] 
:2,$s/\t/,/g 

說明:

首先,我們定義一個宏 'Q',將有取代一個標籤分號。現在,在任何一行上,我們都可以簡單地運行這個宏n次來替換第一個n選項卡。要自動執行該給每一行,我們使用norm命令:

:2,$norm [email protected] 

這基本上是字面上的指定範圍內的每行中輸入[email protected](如「運行宏‘Q’七期」)一樣的東西。從那裏,我們可以簡單地用逗號替換每個選項卡。

:2,$s/\t/,/g 
+1

另外,只是你知道,還有一個[專門的vim站點](http://vi.stackexchange .com),您可以在將來發布您的問題。 – DJMcMayhem

+0

似乎是一個堅實的迴應,我會立即測試它。什麼是'\ '用於? –

+0

''\ 「'是您描述文字回車的方式。以這種方式輸入是非常重要的,以便替換命令實際上已經運行。否則,你最終會得到像s/\ t /;:s/\ t /;:s/\ t /;:s/\ t /;:s/\ t /;:s/\ t /;:s/\ t /;'和vim等着你打進。 – DJMcMayhem

0
:2,$s/\t\(.*\t\)\@=/;/g 
:2,$s/\t/, 
  • 更改任何選項卡,那裏是一個標籤以後;
  • 更改任何剩餘的選項卡,

編輯:誤解。這裏有一個固定的版本:

:2,$s/\(\(\t.*\)\{7}\)\@<=\t/,/g 
:2,$s/\t/;/g 
  • 變化之前,那裏的七個選項卡來,
  • 更改任何剩餘的選項卡的任何選項卡;
+0

當我看到你的答案時,最後一個標籤被逗號替換。然而,並不是每一道線條都是一樣的,所以玩家可以有一個俱樂部:那麼它需要沒有逗號,或者玩家可以有3個俱樂部,那麼它需要兩個逗號 –

0

PatternsOnText plugin有(其中包括)一個:SubstituteSelected命令,允許指定匹配位置。有了這個,你可以很容易地更換前8個標籤使用分號,然後使用常規的替代品來改變剩餘接頭插入逗號:

:2,$SubstituteSelected/\t/;/g 1-8 
:2,$s/\t/,/g 
+0

是的,我看過你的(或他人)的插件,但是我寧願在沒有插件的情況下完成它,因爲解決方案應該由老師重現。我找到答案,但會回答我自己。感謝你的回答! –

0

我們僅通過手動捕獲第8組([^\t]*\t)(...)(...),然後解決問題用分號分隔它們(\1;\2;...;)然後用逗號替換剩餘的選項卡| 2,$s/\t/,/g

感謝大家試圖幫助!

相關問題