2009-10-15 31 views
16

不使用任何編程語言。只使用正則表達式。可能嗎?查找重複行並使用正則表達式刪除替換功能

例如輸入>>

11 
22 
22 <-must remove 
33 
44 
44 <-must remove 
55 

輸出>>

11 
22 
33 
44 
55 
+7

正則表達式是由一些程序(SED,Perl,Python和JAVA,東西)執行。 「不使用任何編程語言」沒有任何意義。什麼程序運行正則表達式? – 2009-10-15 16:08:58

+0

是的,除了S.Lott所說的,你必須更好地說明「刪除」是什麼意思。刪除所有重複行嗎?或刪除所有,但一個?如果後者,你想保留哪一個,第一個還是最後一個?或者順序無關緊要? – Davide 2009-10-15 16:37:05

+0

最後,應該一次運行,還是允許多次傳球? – Davide 2009-10-15 16:37:50

回答

42

Regular-expressions.info對Deleting Duplicate Lines From a File

頁這基本上可以歸結爲尋找這個oneliner:

^(.*)(\r?\n\1)+$ 

...並替換爲\1
注:點必須不匹配換行符

說明:

caret將只在一行的開始匹配。所以正則表達式引擎只會嘗試匹配那裏的正則表達式的其餘部分。 dotstar組合只需匹配整條線,無論其內容如何。括號將匹配的行存儲到第一個反向引用中。

接下來我們將匹配行分隔符。我把question mark納入\r?\n,使這個正則表達式可以同時使用Windows(\r\n)和UNIX(\n)文本文件。所以直到這一點,我們匹配一條線和下面的換行符。

現在我們需要檢查這個組合是否跟着同一行的副本。我們只需要\1。這是我們匹配的第一個反向引用。反向引用將匹配相同的文本。

如果反向引用無法匹配,則會丟棄正則表達式匹配和反向引用,並且正則表達式引擎會在下一行的開始處再次嘗試。如果反向引用成功,則正則表達式中的plus symbol將嘗試匹配該行的其他副本。最後,dollar symbol強制regex引擎檢查反向引用所匹配的文本是否爲完整行。我們已經知道反向引用匹配的文本前面有一個換行符(匹配\ r?\ n)。因此,我們現在檢查它是否也跟着一個換行符,或者它是否在使用dollar sign的文件末尾。

整個比賽變成line\nline(或line\nline\nline等)。因爲我們正在進行搜索和替換,所以它們之間的行,重複項和換行符都將從文件中刪除。因爲我們希望保持原來的路線,而不是重複,我們使用\1作爲替換文本把原線回。

3

見我的更多信息的要求,我回答的容易現在方式

  1. 如果順序並不重要,只是一個

    排序-u

    會做的伎倆

  2. 如果訂單沒有問題,但你不介意再可以使用:

    %s/\(。* \)\(\ _。* \)\(\ 1 \)/ \ 2 \ 1/g

    保存最後一次出現,或

    %S/\(。* \)\(\ _。* \)\(\ 1 \)/ \ 1 \ 2 /克

    保存第一次出現。

如果你確實想重新運行多次通行證,那就更難了,所以在我們開始工作之前,請在問題中這麼說!

編輯:在您的編輯你不是很清楚,但它看起來像你想只是一個單一的通重複相鄰的線拆除!那麼,這很容易!

簡單:

/(.*)\1*/\1/ 

(在vim /\(.*\)\1*/\1/),即尋找(.*)\1*,並與剛剛\1取代它會做的伎倆

+0

'(。*)\ 1 *'與重複行不匹配,因爲正則表達式中沒有任何內容與行和重複行之間的換行符匹配。 – 2010-02-27 10:24:07

3

在使用RegexBuddy,你可以做到這一點,如下所示:

  1. 在庫選項卡上,如果默認情況下未加載,則加載RegexBuddy.rbl庫。
  2. 在查找框中輸入「duplicate」
  3. 單擊使用按鈕加載「刪除重複行」正則表達式。
  4. 在GREP選項卡,指定要從刪除重複的文件的文件夾和文件掩碼。
  5. 在GREP按鈕的下拉菜單中選擇執行。

如果您只對一個文件進行此操作,則可以使用「測試」選項卡代替「GREP」選項卡。在「測試」選項卡上加載文件,然後單擊主工具欄中的「替換」按鈕。