Python 模块之 Difflib
Difflib作为python的标准库,无需安装,作用是对比文本之间的差异,而且支持输出可读性比较强的HTML文档。
在Linux下,可以直接使用vimdiff命令比对文本,例如对a.txt与b.txt的差异,命令: vimdiff a.txt b.txt 即可。
如下图:
常见的函数介绍:
可以用于创建一个完整HTML文件,该文件显示具有行间和行内更改突出的文本的逐行比较。
[]中的参数为可选项。
比较fromlines和tolines(字符串列表)并返回一个字符串,该字符串是一个完整的HTML文件,其中包含一个表格,显示逐行差异,突出显示行间和行内更改。
fromdesc和todesc是可选的关键字参数,用于指定从/到文件列标题字符串(默认为空字符串)。
context和numlines都是可选的关键字参数。设置方面,以True当背景的差异将被显示,否则默认为False可显示完整的文件。numlines默认为5。
3、make_table(fromlines,tolines [,fromdesc] [,todesc] [,context] [,numlines] )
比较fromlines和tolines(字符串列表)并返回一个字符串,该字符串是一个完整的HTML表格,显示逐行差异,突出显示行间和行内更改。此方法的参数与方法的参数相同make_file()。和make_file()的主要区别在于不能明显显示两个文档之间的差异。
# -*- coding: utf-8 -*-
import sys
import difflib
def read_file(filename):
try:
with open(filename, 'r') as f:
return f.readlines()
except IOError:
print("ERROR: 没有找到文件:%s或读取文件失败!" % filename)
sys.exit(1)
def compare_file(file1, file2, out_file):
file1_content = read_file(file1)
file2_content = read_file(file2)
d = difflib.HtmlDiff()
result = d.make_file(file1_content, file2_content)
with open(out_file, 'w') as f:
f.writelines(result)
if __name__ == '__main__':
compare_file(r'C:\Users\source\pycode\code5\a.txt', r'C:\Users\source\pycode\code5\b.txt', r'C:\Users\source\pycode\code5\result.html')
4、Differ()和compare()
class difflib.Differ([ linejunk [,charjunk ] ] )
可选关键字参数linejunk和charjunk用于过滤函数(或None),默认值是None
compare(a,b)
比较两个行序列,并生成delta(一系列行)。
每个序列必须包含以换行符结尾的单个单行字符串。可以从readlines()类文件对象的方法获得这样的序列。生成的增量也包括换行符终止的字符串,可以通过类writelines()文件对象的方法按原样打印。
# coding=utf-8
from __future__ import print_function
import difflib
text1 = '''
I love BANK OF NINGBO
I very love NINGBO
She's the city I love the most.
'''
text2 = '''
I love BANK OF China
I very love China
I'm his favorite person.
'''
d = difflib.Differ()
list1 = list(d.compare(text1,text2))
for line in list1:
if line == "\n":
print ("\n")
print("%s" %line,end='')
结果如下:
其中‘-’,‘+’,‘ ’,‘?’的含义如下:
码 |
含义 |
'- ' |
序列1独有的行 |
'+ ' |
序列2独有的行 |
' ' |
两个序列共有的线 |
'? ' |
两个输入序列中都不存在该行 |
5、ratio()
返回序列相似性的度量,作为[0,1]范围内的浮点数
import difflib
s = difflib.SequenceMatcher(None, "abcd", "bcde")
s.ratio()
结果为0.75