2013-04-18 11 views
9

Desidero scrivere una semplice applicazione diff in Python utilizzando Google's Diff Match Patch APIs. Sono abbastanza nuovo in Python, quindi voglio un esempio di come usare l'API Diff Match Patch per confrontare semanticamente due paragrafi di testo. Non sono troppo sicuro su come utilizzare il file diff_match_patch.py e cosa importare da esso. L'aiuto sarà molto apprezzato!Implementazione dell'API DiffMatchPatch di Google per Python 2/3

Inoltre, ho provato a utilizzare difflib, ma l'ho trovato inefficace per il confronto di frasi ampiamente diverse. Sto usando Ubuntu 12.04 x64.

risposta

18

Google diff-match-patch API è lo stesso per tutte le lingue in cui è implementato (Java, JavaScript, Dart, C++, C#, Objective C, Lua e Python 2.xo python 3.x). Pertanto, in genere si possono usare frammenti di campionamento in lingue diverse dalla propria lingua di destinazione per capire quali particolari chiamate API sono necessarie per varie attività di diff/match/patch.

Nel caso di un semplice confronto "semantica", questo è ciò che vi serve

import diff_match_patch 

textA = "the cat in the red hat" 
textB = "the feline in the blue hat" 

#create a diff_match_patch object 
dmp = diff_match_patch.diff_match_patch() 

# Depending on the kind of text you work with, in term of overall length 
# and complexity, you may want to extend (or here suppress) the 
# time_out feature 
dmp.Diff_Timeout = 0 # or some other value, default is 1.0 seconds 

# All 'diff' jobs start with invoking diff_main() 
diffs = dmp.diff_main(textA, textB) 

# diff_cleanupSemantic() is used to make the diffs array more "human" readable 
dmp.diff_cleanupSemantic(diffs) 

# and if you want the results as some ready to display HMTL snippet 
htmlSnippet = dmp.diff_prettyHtml(diffs) 


Una parola sul "semantica" trattamento da diff-partita-patch
Attenzione che tale l'elaborazione è utile per presentare le differenze a un osservatore umano perché tende a produrre una lista più breve di differenze evitando la risincronizzazione non rilevante dei testi (quando ad esempio due parole distinte capita di avere lettere comuni nella loro metà). Tuttavia, i risultati prodotti sono tutt'altro che perfetti, poiché questa elaborazione è una semplice euristica basata sulla lunghezza delle differenze e dei pattern di superficie ecc. Piuttosto che sull'effettiva elaborazione NLP basata su lessici e altri dispositivi a livello semantico.
Ad esempio, i textA e textB valori usati sopra produrre il seguente "prima e dopo-diff_cleanupSemantic" valori per la diffs matrice

[(0, 'the '), (-1, 'cat'), (1, 'feline'), (0, ' in the '), (-1, 'r'), (1, 'blu'), (0, 'e'), (-1, 'd'), (0, ' hat')] 
[(0, 'the '), (-1, 'cat'), (1, 'feline'), (0, ' in the '), (-1, 'red'), (1, 'blue'), (0, ' hat')] 

piacevole! la lettera "e" che è comune al rosso e al blu fa sì che il diff_main() veda quest'area del testo come quattro modifiche, ma cleanupSemantic() corregge come solo due modifiche, individuando con cura i diversi sem "blu" e " rosso'.

Tuttavia, se abbiamo, per esempio

textA = "stackoverflow is cool" 
textb = "so is very cool" 

La prima/dopo le matrici prodotte sono:

[(0, 's'), (-1, 'tack'), (0, 'o'), (-1, 'verflow'), (0, ' is'), (1, ' very'), (0, ' cool')] 
[(0, 's'), (-1, 'tackoverflow is'), (1, 'o is very'), (0, ' cool')] 

che dimostra che il presunto semanticamente migliorato dopo può essere piuttosto indebitamente " torturato "rispetto allo prima dello. Si noti, ad esempio, come il leader 's' è mantenuto come una corrispondenza e come la parola 'very' aggiunta è mescolata con parti dell'espressione 'is cool'. Idealmente, ci aspetteremmo probabilmente qualcosa come

[(-1, 'stackoverflow'), (1, 'so'), (0, ' is '), (-1, 'very'), (0, ' cool')] 
+0

Grazie per la rapida risposta! Questo è molto utile e l'algoritmo è molto buono, ma non lo trovo esattamente "leggibile". È possibile dare un output formattato [come questo] (http://neil.fraser.name/software/diff_match_patch/svn/trunk/demos/demo_diff.html) usando invece Python e queste API? E come potrei farlo se è possibile? – shortstheory

+1

Vedere modifica, nella parte inferiore della prima sezione del codice. Essenzialmente è necessario chiamare 'dmp.diff_prettyHtml (diffs) 'che produce uno snippet HTML adatto a mostrare le varie modifiche (inserzioni e cancellazioni) nel colore codificato. – mjv

+0

Grazie! Questo è perfetto ed è proprio quello che stavo cercando! Apprezzo tutto il tuo aiuto! Tuttavia, voglio anche sapere se è possibile fornire anche l'output raw. Avrei svalutato la tua risposta, ma non ho abbastanza reputazione. – shortstheory

Problemi correlati