2015-07-31 13 views
10

Utilizzando Python, mi piacerebbe produrre la differenza tra due stringhe come una unificata diff (-u) mentre, facoltativamente, ignorando le righe vuote (-B) e gli spazi (-w)."diff -u -B -w" in python?

Poiché le stringhe sono state generate internamente, preferirei non affrontare la complessità sfumata di scrivere una o entrambe le stringhe in un file, eseguire GNU diff, correggere l'output e infine ripulire.

Mentre difflib.unified_diff genera differenze unificate non sembra consentirmi di modificare come vengono gestiti gli spazi e le righe vuote. Ho esaminato la sua implementazione e, sospetto, l'unica soluzione è copiare/hackerare il corpo di quella funzione.

C'è qualcosa di meglio?

Per il momento mi sto nudo i caratteri pad usando qualcosa come:

import difflib 
import re 
import sys 

l = "line 1\nline 2\nline 3\n" 
r = "\nline 1\n\nline 2\nline3\n" 
strip_spaces = True 
strip_blank_lines = True 

if strip_spaces: 
    l = re.sub(r"[ \t]+", r"", l) 
    r = re.sub(r"[ \t]+", r"", r) 
if strip_blank_lines: 
    l = re.sub(r"^\n", r"", re.sub(r"\n+", r"\n", l)) 
    r = re.sub(r"^\n", r"", re.sub(r"\n+", r"\n", r)) 
# run diff 
diff = difflib.unified_diff(l.splitlines(keepends=True), r.splitlines(keepends=True)) 
sys.stdout.writelines(list(diff)) 

che, naturalmente, si traduce in uscita per vedere le differenze di qualcosa di qualcosa di diverso l'ingresso originale. Ad esempio, passare il testo sopra a GNU diff 3.3 eseguito come "diff -u -w" e "line 3" viene visualizzato come parte del contesto, il precedente mostrerebbe "line3".

+0

"che, naturalmente, risulta in diff per qualcosa di diverso dall'input originale." Certo, ma questo è ciò che diff fa, giusto? OTOH, sono sicuro che diff sostituisce gli spazi bianchi con un singolo spazio vuoto anziché senza spazi ... –

+0

GNU diff 3.3 descrive -w così: "L'opzione' --ignore-all-space '('-w') è più forte ignora le differenze anche se una riga ha uno spazio bianco in cui l'altra linea non ne ha. ... " – cagney

+1

@patrick No, diff usa l'input originale quando visualizza il contesto (e ciò include cose come i numeri di riga corretti), non qualcosa alterato oltremisura – cagney

risposta

1

Crea il tuo SequenceMatcher, copia il corpo unified_diff e sostituisci SequenceMatcher con il tuo dispositivo di corrispondenza.

Problemi correlati