2014-07-14 16 views
7

Ho file di testo con righe di testo ripetute, ma ne voglio solo uno. Immaginate questo file di testo:Estrai tutte le righe univoche

AAAAA 
AAAAA 
AAAAA 
BB 
BBBBB 
BBBBB 
CCC 
CCC 
CCC 

vorrei solo bisogno dei seguenti quattro linee da esso:

AAAAA 
BB 
BBBBB 
CCC 

sto usando un editor di testo (EmEditor o Notepad ++), che supporta RegEx, non un linguaggio di programmazione, quindi devo usare un'espressione puramente regolare.

Qualsiasi aiuto?

MODIFICA: Ho controllato l'altro thread menzionato da hsz e vorrei chiarire che questo non è lo stesso. Sebbene entrambi debbano rimuovere linee duplicate, il modo per ottenerlo è diverso. Ho bisogno di puro RegEx, ma la migliore risposta dell'altro thread si basa su uno specifico plug-in Notepad ++ (che non viene nemmeno più con esso), quindi non è nemmeno una soluzione regex. Il secondo caso è una regex e funziona su Notepad ++, ma non su EmEditor, che anch'io ho bisogno. Quindi non penso che la mia domanda sia una ripetizione di quello, sebbene quel collegamento sia utile, e quindi ringrazio hsz per questo.

+0

possibile duplicato del [Rimozione righe duplicate in Notepad ++] (http://stackoverflow.com/questions/3958350/removing-duplicate-rows-in-notepad) – hsz

+0

sono linee ripetute raggruppate? Cioè, il file può essere AAAA BBBB AAAA BBBB in modo da renderlo AAAA BBBB? –

+0

Risposta a Gelbukh: Le linee devono essere nello stesso ordine in cui erano originariamente. –

risposta

7

Due opzioni quasi identici:

Partita tutte le linee che non sono ripetute

(?sm)(^[^\r\n]+$)(?!.*^\1$) 

Le linee saranno abbinate, ma per estrarre loro, si vuole veramente sostituire gli altri.

sostituire tutte le linee ripetute

Questo funziona meglio in Notepad ++:

Ricerca: (?sm)(^[^\r\n]*)[\r\n](?=.*^\1)

Sostituire: stringa vuota

  • (?s) attiva la modalità DOTALL, permettendo il punto da abbinare su tutte le linee
  • (?m) Attiva la modalità multi-linea, permettendo ^ e $ per abbinare su ogni riga
  • (^[^\r\n]*) cattura una linea al gruppo 1, vale a dire
  • L'ancora ^ afferma che siamo all'inizio della stringa
  • [^\r\n]* corrisponde a qualsiasi caratteri che non sono i caratteri di nuova linea
  • [\r\n] partite i caratteri di nuova riga
  • Il lookahead (?!.*^\1$) afferma che siamo in grado di adattarsi a qualsiasi numero di c haracters .*, quindi ...
  • ^\1$ stessa linea Gruppo 1
+0

Aggiunta un'opzione, "Sostituisci tutte le linee ripetute", che funzionerà meglio in un editor di testo poiché si desidera "estrarre" le linee. – zx81

+0

Grazie mille. Il tuo secondo RegEx (Sostituisci tutte le linee ripetute) è ciò di cui ho bisogno. Il primo fa il contrario (ma potrebbe essere utile, quindi lascia che sia). Funziona allo stesso modo sia su EmEditor che su Notepad ++, ma non rimuove le linee vuote. :(Ho già provato ad aggiungere '|^\ n $' alla fine, ma non fa nulla.Se potessi semplicemente darmi una mano, questa sarebbe la migliore risposta :) –

+0

Si prega di consultare la risposta rivista. Se questo funziona per te, considera di accettare la risposta facendo clic sul segno di spunta a sinistra poiché questo è il sistema di replica che funziona sul sito. Grazie! – zx81

0

A condizione che le linee uguali vanno in gruppi, cioè, AAAA AAAA BBBB BBBB e non AAAA BBBB AAAA BBBB, in Perl notazione, i seguenti lavori:

s/(^.*$)(\r?\n\1$)*/$1/gm; 

che significa sostituto/(^. $) (\ r? \ n \ 1 $)/per $ 1 globalmente e in modalità multilinea (^ e $ corrisponde interno \ n).

Questa espressione indica che qualsiasi riga completa seguita da un numero qualsiasi di righe uguali viene sostituita da una singola occorrenza.

Vedere la guida sul proprio editor specifico per come applicare una regex.

+0

grazie, ma questo non è per un semplice editor di testo come richiesto. L'ho provato senza le parti finali, ma ancora non funziona. –

0

Non so funzionerà in Notepad ++ o EmEditor, ma funziona bene in PHP/JavaScript/Python con sostituzione.

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

Ecco Demo

semplicemente copiare il testo e ottenere il risultato finale dal link che mi hai condiviso.

+1

Grazie per il collegamento, il debugger è utile. Tuttavia, il regex ha bisogno di sostituire qualsiasi carattere non solo lettere, e quindi non ho effettivamente avuto bisogno. Quindi ho sostituito \ w con. ma ora è tutto in EmEditor e Notepad ++, anche se "funziona" bene sul debugger ... Forse sta usando uno standard regex diverso ... –

+0

non so perché non funziona nel notepadd ++ – Braj

2

È possibile utilizzare la seguente espressione regolare per rimuovere entrambe le righe ripetute e vuote.

Find: ^(.*)(\r?\n\1)+$ 
Replace: \1 
+0

Grazie. Buona soluzione ma funziona solo su Notepad ++, così com'è. Ho rimosso il punto interrogativo '?'per farlo funzionare su EmEditor, ma rimuove solo poche righe. Penso che questo potrebbe essere un bug di EmEditor (il programma stesso) non un errore del tuo codice, quindi considero corretta questa risposta. Tuttavia, dal momento che dovevo sceglierne solo uno migliore, ho scelto quello di zx81, perché la sua risposta è dettagliata, non richiede alcuna sostituzione (più pratica) e rimuove anche qualsiasi riga vuota che potrebbe essere nel file originale (qualcosa di cui avevo anche bisogno) e, naturalmente, funziona come lo è in entrambi i direttori. –