python 中是否有一种“开箱即用”的方法来生成两个文本之间的差异列表,然后将此差异应用于一个文件以稍后获取另一个文件?

我想保留文本的修订历史记录,但如果只有一行已编辑的行,我不想保存每个修订的整个文本。我在看 差异库, ,但我不知道如何生成仅包含已编辑行的列表,该列表仍可用于修改一个文本以获取另一个文本。

有帮助吗?

解决方案

你看看DIFF匹配补丁从谷歌? Apparantly Google文档使用这套algoritms的。它不仅包括差异模块,也是一个补丁模块,这样你就可以生成从旧文件和diff文件最新的文件。

一个蟒版本包含。

http://code.google.com/p/google-diff -match贴片/

其他提示

不difflib.unified_diff想得到你想要什么?有这里rel="noreferrer">。

AFAIK最DIFF算法使用一个简单的最长公共子序列匹配,以找到公共部分两个文本和任何留下被认为是差异之间。它不应该是太困难的代码了自己的动态规划算法来实现,在蟒蛇,维基百科网页上面提供的算法了。

我已经实现了一个纯 python 函数来应用 diff 补丁来恢复任一输入字符串,我希望有人发现它有用。它使用解析 统一差异格式.

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

如果有标题行 ("--- ...\n","+++ ...\n") 它会跳过它们。如果我们有一个统一的 diff 字符串 diffstr 代表之间的差异 oldstrnewstr:

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

在Python中,你可以使用以下命令生成两个字符串的统一差异 差异库 (标准库的一部分):

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

在 UNIX 上: diff -U0 a.txt b.txt

代码位于 GitHub 上,并使用 ASCII 和随机 unicode 字符进行测试: https://gist.github.com/noporpoise/16e731849eb1231e8​​6d78f9dfeca3abc

它必须是一个python溶液?结果 我的第一个想法,以一个解决办法是要么使用一个版本控制系统(颠覆,GIT中,等)或是diff / patch实用程序与UNIX系统的标准,或者是用于cygwin基于窗口的系统的一部分。

也许你可以使用 unified_diff 以生成一个文件差异列表。只有更改文本在文件中可以写入到一个新的文本文件,你可以用它为你的将来参考。 这是一个可以帮助你只写了差到新文件的代码。 我希望这是你所要求的!

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 

使用这个在你的代码只保存差分输出!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top