2013-02-01 14 views
7

Desidero confrontare due documenti indipendentemente dalle interruzioni di riga. Se il contenuto è lo stesso, ma la posizione e la quantità delle interruzioni di riga sono diverse, voglio mappare le linee di un documento alle righe nell'altro.Confronto di due documenti usando regex

Dato:

Documento 1

I went to Paris in July 15, where I met some nice people. 
And I came back 
to NY in Aug 15. 
I am planning 
to go there soon 
after I finish what I do. 

Documento 2

I went 
to Paris 
in July 15, 
where I met 
some nice people. 
And I came back to NY in Aug 15. 
I am planning to go 
there soon after I finish what I do. 

voglio un algoritmo in grado di determinare che la linea 1 nel documento 1 contiene lo stesso testo di righe da 1 a 5 nel documento 2, le righe 2 e 3 del documento 1 contengono lo stesso testo della riga 6 nel documento 2, ecc.

1 = 1,2,3,4,5 
2,3 = 6 
4,5,6 = 7,8 

C'è un modo con espressioni regolari per abbinare ogni riga in ogni documento, se si estende su più righe negli altri documenti?

+0

Quali sono quei numeri? –

+0

Un approccio sarebbe semplicemente quello di dividere entrambi gli input in parole, mantenendo le linee da cui provengono, e le parole corrispondono le parole una per una (assumendo che le parole siano le stesse). – nneonneo

+0

le righe corrispondenti a ciascun documento – hmghaly

risposta

0

È possibile scorrere ogni riga di doc1 e fare qualcosa del genere:

searchstring = line.replace(' ', '[ |\n]')

Poi fare una ricerca su doc2 utilizzare questa stringa di ricerca.

match = re.search(searchstring, contents)

Se match è NULL, poi c'era alcuna corrispondenza. Else, match.group(0) vi darà i contenuti corrispondenti del doc 2.

'I went\nto Paris\nin July 15,\nwhere I met\nsome nice people.'

Allora è un semplice esercizio di scissione che da '\ n' e cercare di capire quali linee in doc2 sono venuti.

2

Io non sono un programmatore python, ma questo non sembra un problema che può essere risolto con espressioni regolari.

invece, che ci si vuole prima di confrontare i documenti per assicurarsi che il contenuto è la (temporaneamente rimuovere tutti ritorni a capo in anticipo) stessa. Non so cosa vuoi fare se non lo è, quindi non ho intenzione di affrontarlo.

creare una collezione di collezioni intero chiamato linemappings

Iniziare un ciclo. Il ciclo passerà attraverso ogni personaggio in ogni documento contemporaneamente. Avrai bisogno di quattro variabili contatore. charindex1 conterrà l'indice carattere attuale nel Documento 1 e charindex2 conterrà l'indice charater corrente nel documento 2. lineindex1 conterrà l'indice di riga corrente nel documento 1 e lineindex2 conterrà l'indice di riga corrente nel documento 2.

Inizia con le variabili dell'indice char su 0 e le variabili dell'indice di riga inizializzate su 1.

Inizio loop:

Prendi il carattere corrente da ogni documento: char1 dal documento 1 e char2 dal documento 2.

Se char1 E char2 sono entrambi a capo o nessuno dei due sono a capo, quindi anticipare entrambi charindex1 e charindex2 di 1.
Else Se char1 è una nuova riga, quindi anticipare charindex1 di 1.
Else Se char2 è un ritorno a capo, poi avanzare charindex2 di 1.

se uno o char1char2 è un ritorno a capo, quindi inserire un nuovo record nella collezione linemappings (il risultato alla fine sarà qualcosa come [[1,1],[1,2],[1,3],[1,4],[1,5],[2,6],[3,6],[4,7],[5,7],[6,7],[6,8])

Se char1 è una nuova riga, avanzare lineindex1 di 1.
Se char2 è una nuova riga, avanzare lineindex2 di 1.

Ciclo fino al raggiungimento della fine dell'ingresso.

(non ho potuto testare questo dato che io non sono un programmatore python, ma spero che si ottiene l'essenza e può modificarlo secondo le proprie esigenze.)

+0

@TerryLi ha una risposta migliore. Ci andrei, personalmente. – JDB

3
import java.io.File; 
import java.io.IOException; 
import java.util.ArrayList; 
import org.apache.commons.io.FileUtils; 

public class Compare { 
    public static void main(String[] args) throws IOException { 
     String doc1 = FileUtils.readFileToString(new File("Doc1.txt")); 
     String doc2 = FileUtils.readFileToString(new File("Doc2.txt")); 
     String[] array1 = doc1.split("\n"); 
     String[] array2 = doc2.split("\n"); 
     int[] count1 = new int[array1.length]; 
     int[] count2 = new int[array2.length]; 
     int sum1 = 0; 
     int sum2 = 0; 
     for (int i=0;i<count1.length;i++) { 
      count1[i] = sum1 + array1[i].split(" ").length; 
      sum1 = count1[i]; 
     } 
     for (int i=0;i<count2.length;i++) { 
      count2[i] = sum2 + array2[i].split(" ").length; 
      sum2 = count2[i]; 
     } 
     ArrayList<Integer> result1 = new ArrayList<Integer>(); 
     ArrayList<Integer> result2 = new ArrayList<Integer>(); 
     for (int j=0; j<count1.length;) { 
      for (int k=0; k<count2.length;) { 
       if (count1[j]==count2[k]) { 
        result1.add(j+1); 
        result2.add(k+1); 
        System.out.println(result1.toString()+" = "+result2.toString()); 
        result1 = new ArrayList<Integer>(); 
        result2 = new ArrayList<Integer>(); 
        j++;k++; 
       } else if (count1[j]>count2[k]) { 
        result2.add(k+1); 
        k++; 
       } else { 
        result1.add(j+1); 
        j++; 
       } 
      } 
     } 
    } 
} 

Esempio di output:

[1] = [1, 2, 3, 4, 5] 
[2, 3] = [6] 
[4, 5, 6] = [7, 8] 

Codice Java completo e funzionante. Non è una soluzione regex, quindi potrebbe non adattarsi alle tue necessità.

L'idea è di creare una matrice per ogni documento. La dimensione dell'array è uguale al numero di linee in ogni documento. L'ennesimo elemento dell'array memorizza il numero di parole visualizzate fino all'ennesima riga del documento. Quindi identifichiamo quegli elementi uguali in entrambi gli array, i cui indici definiscono gli intervalli dell'output.