生成和蟒蛇
你看看从谷歌DIFF匹配补丁?大致google Docs使用这套算法。它不仅包含diff模块,还包含修补程序模块,因此您可以使用旧文件和差异文件生成最新的文件。
包含一个python版本。
据我所知大多数差异算法使用简单Longest Common Subsequence匹配,找到两个文本,无论是离开被认为是差的公共部分。编写自己的动态编程算法来完成python中的代码不应该太困难,上面的维基百科页面也提供了该算法。
是否difflib.unified_diff想得到你想要什么?有一个例子here。
投票你的答案。内置的difflib看起来很强大,但有点令人困惑,只是学习曲线的问题。在这里看到我的类似帖子:http://stackoverflow.com/questions/4743359/python-difflib-deltas-and-compare-ndiff/4743621#4743621 – NealWalters 2011-01-21 16:38:21
该库没有办法应用'difflib.unified_diff'的输出。它有'diff',但没有'patch'。因此,如果你想保持在python中,'difflib.unified_diff'是没有用的。 – 2016-01-07 05:23:52
也许你可以使用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
在您的代码中使用此选项可仅保存差异输出!
我已经实现了一个纯Python功能适用差异补丁,以恢复或者输入字符串,我希望有人发现它是有用的。它使用分析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
如果有标题行("--- ...\n","+++ ...\n")
它跳过它们。如果我们有一个统一的diff串diffstr
代表oldstr
和newstr
之间的差异:使用difflib(标准库的一部分)
# 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/16e731849eb1231e86d78f9dfeca3abc
正是我在找的东西!我试着用google搜索“python”,“diff”,“patch”,“revision”的不同组合,但还没有找到。 – noio 2010-02-22 13:08:36
谷歌差异匹配补丁似乎存储整个文件。它将所有元素都保存在元组中:(0,'stuff')表示'stuff'出现在两个字符串中。该系统非常简单,它存储了字面上的每个字符,以便它可以遍历它们并根据需要修改文本。 – Paragon 2012-05-05 00:54:05
我如何使用这个API与Python>?如果可以用例子 – qre0ct 2013-05-15 04:47:32