Frage

Gibt es eine ‚out-of-the-box‘ Art und Weise in Python eine Liste der Unterschiede zwischen zwei Texten zu erzeugen, und dann diese diff auf eine Datei der Anwendung den anderen zu erhalten, später?

Ich will die Revisionsgeschichte eines Textes halten, aber ich will nicht den gesamten Text für jede Revision speichern, wenn es nur eine einzige bearbeitete Linie ist. Ich schaute auf difflib , aber ich konnte nicht sehen, wie eine Liste nur zu erzeugen, die editierten Linien, die verwendet werden können, noch einen Text zu modifizieren, um die andere zu erhalten.

War es hilfreich?

Lösung

Haben Sie einen Blick auf diff-match-Patch von Google? Apparantly Google Text & Tabellen diesen Satz von Algorithmen, verwendet. Es enthält nicht nur ein Diff-Modul, sondern auch ein Patch-Modul, so dass Sie die neueste Datei von älteren Dateien und diffs erzeugen können.

Eine Python-Version enthalten ist.

http://code.google.com/p/google-diff -match-patch /

Andere Tipps

Does difflib.unified_diff wollen Sie wollen? Es gibt ein Beispiel rel="noreferrer">.

AFAIK meisten diff Algorithmen verwenden eine einfache Längste gemeinsame Subsequence Spiel, den gemeinsamen Teil zu finden zwischen zwei Texten und was links ist der Unterschied berücksichtigt wird. Es sollte nicht allzu schwierig, bis Sie Ihren eigenen dynamischen Programmieralgorithmus, um Code zu erreichen, dass in Python, die Wikipedia-Seite oben zu dem Algorithmus bereitstellt.

ich eine reine Python-Funktion implementiert haben diff Patches gelten entweder der Eingabezeichenfolgen zu erholen, ich hoffe jemand findet es nützlich. Es nutzt Analysiert das Unified-diff-Format .

import re

_hdr_pat = re.compile("^@@ -(\d+),?(\d+)? \+(\d+),?(\d+)? @@$")

def apply_patch(s,patch,revert=False):
  """
  Apply unified diff patch to string s to recover newer string.
  If revert is True, treat s as the newer string, recover older string.
  """
  s = s.splitlines(True)
  p = patch.splitlines(True)
  t = ''
  i = sl = 0
  (midx,sign) = (1,'+') if not revert else (3,'-')
  while i < len(p) and p[i].startswith(("---","+++")): i += 1 # skip header lines
  while i < len(p):
    m = _hdr_pat.match(p[i])
    if not m: raise Exception("Cannot process diff")
    i += 1
    l = int(m.group(midx))-1 + (m.group(midx+1) == '0')
    t += ''.join(s[sl:l])
    sl = l
    while i < len(p) and p[i][0] != '@':
      if i+1 < len(p) and p[i+1][0] == '\\': line = p[i][:-1]; i += 2
      else: line = p[i]; i += 1
      if len(line) > 0:
        if line[0] == sign or line[0] == ' ': t += line[1:]
        sl += (line[0] != sign)
  t += ''.join(s[sl:])
  return t

Wenn es Kopfzeilen ("--- ...\n","+++ ...\n") es überspringt sie. Wenn wir eine einheitliche diff Zeichenfolge diffstr, die die diff zwischen oldstr und newstr:

# recreate `newstr` from `oldstr`+patch
newstr = apply_patch(oldstr, diffstr)
# recreate `oldstr` from `newstr`+patch
oldstr = apply_patch(newstr, diffstr, True)

In Python können Sie eine einheitliche diff von zwei Strings erzeugen mit difflib (Teil der Standardbibliothek):

import difflib
_no_eol = "\ No newline at end of file"

def make_patch(a,b):
  """
  Get unified string diff between two strings. Trims top two lines.
  Returns empty string if strings are identical.
  """
  diffs = difflib.unified_diff(a.splitlines(True),b.splitlines(True),n=0)
  try: _,_ = next(diffs),next(diffs)
  except StopIteration: pass
  return ''.join([d if d[-1] == '\n' else d+'\n'+_no_eol+'\n' for d in diffs])

Auf Unix: diff -U0 a.txt b.txt

-Code ist auf GitHub hier zusammen mit Tests unter Verwendung von ASCII und zufälligen Unicode-Zeichen: https: // Kern. github.com/noporpoise/16e731849eb1231e86d78f9dfeca3abc

Hat es eine Python-Lösung sein?
Meine erste Gedanken als zu einer Lösung wären entweder ein Versionskontrollsystem (Subversion, Git, etc.) oder den diff / patch Dienstprogramme zu verwenden, die mit einem Unix-System-Standard, oder sind Teil von cygwin für ein Windows-basiertes System.

Wahrscheinlich können Sie verwenden unified_diff die Liste der Unterschied in einer Datei zu erzeugen, . Nur die geänderten Texte in der Datei kann in eine neue Textdatei geschrieben werden, wo Sie es für Ihre zukünftige Referenz verwenden können. Dies ist der Code, den Sie nur den Unterschied zu Ihrer neuen Datei schreiben hilft. Ich hoffe, das ist das, was Sie fordern!

diff = difflib.unified_diff(old_file, new_file, lineterm='')
    lines = list(diff)[2:]
    # linesT = list(diff)[0:3]
    print (lines[0])
    added = [lineA for lineA in lines if lineA[0] == '+']


    with open("output.txt", "w") as fh1:
     for line in added:
       fh1.write(line)
    print '+',added
    removed = [lineB for lineB in lines if lineB[0] == '-']
    with open("output.txt", "a") as fh1:
     for line in removed:
       fh1.write(line)
    print '-',removed 

Verwenden Sie diese in Ihrem Code nur den Differenzausgang zu speichern!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top