Question

Y at-il un « out-of-the-box » façon python pour générer une liste des différences entre les deux textes, puis l'application de cette diff dans un fichier pour obtenir l'autre, plus tard?

Je veux garder l'historique de révision d'un texte, mais je ne veux pas sauver s'il y a une seule ligne a modifié le texte entier pour chaque révision. Je regardais difflib , mais je ne pouvais pas voir comment générer une liste de seulement la les lignes modifiées qui peuvent encore être utilisés pour modifier une texte pour obtenir l'autre.

Était-ce utile?

La solution

Avez-vous un coup d'oeil au diff match-patch de google? Apparantly Google Docs utilise cet ensemble de algoritms. Il comprend non seulement un module de diff, mais aussi un module de patch, de sorte que vous pouvez générer le fichier le plus récent à partir de fichiers anciens et diffs.

Une version python est inclus.

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

Autres conseils

Est-ce que difflib.unified_diff voulez-vous voulez? Il est un exemple .

J'ai mis en place une fonction pure python pour appliquer des patchs diff pour récupérer ou l'autre des chaînes d'entrée, j'espère que quelqu'un juge utile. Il utilise les format diff unifié .

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

S'il y a des lignes d'en-tête ("--- ...\n","+++ ...\n") il saute sur eux. Si nous avons une diffstr chaîne diff unifiée représentant la diff entre oldstr et newstr:

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

En Python, vous pouvez générer un diff unifié de deux chaînes en utilisant difflib (partie de la bibliothèque standard):

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])

Sur unix: diff -U0 a.txt b.txt

Le code est sur GitHub ici ainsi que des tests en utilisant les caractères ASCII et unicode aléatoires: https: // essentiel. github.com/noporpoise/16e731849eb1231e86d78f9dfeca3abc

At-il être une solution python?
Mes premières pensées quant à une solution serait d'utiliser un système de contrôle de version (de Subversion, Git, etc.) ou les services publics diff / patch qui sont standard avec un système unix, ou font partie de cygwin pour un système Windows à base.

vous pouvez probablement utiliser unified_diff pour générer la liste des différences dans un fichier . Seuls les textes modifiés dans votre fichier peut être écrit dans un nouveau fichier texte dans lequel vous pouvez l'utiliser pour votre référence future. Voici le code qui vous permet d'écrire que la différence à votre nouveau fichier. J'espère que c'est ce que vous demandez!

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 

Utilisez dans votre code pour enregistrer uniquement la sortie de différence!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top