本文目录导读:

- 使用Python的
difflib库 - 使用
difflib.SequenceMatcher进行精确比较 - 使用外部工具(subprocess调用)
- 使用第三方库:
deepdiff - 实用工具函数:文件对比
- 命令行脚本版本
- 最佳实践建议
我来介绍几种比对文本差异的常用方法和脚本实现。
使用Python的difflib库
基础文本差异比较
import difflib
def compare_texts(text1, text2):
"""比较两段文本的差异"""
# 将文本按行分割
lines1 = text1.splitlines()
lines2 = text2.splitlines()
# 创建差异比较器
differ = difflib.Differ()
diff = list(differ.compare(lines1, lines2))
return '\n'.join(diff)
# 示例
text_a = """第一行
第二行
第三行
第四行"""
text_b = """第一行
第二行修改
第三行
新增行
第四行"""
result = compare_texts(text_a, text_b)
print(result)
生成HTML格式的差异报告
import difflib
def generate_html_diff(text1, text2):
"""生成HTML格式的差异报告"""
lines1 = text1.splitlines()
lines2 = text2.splitlines()
# 创建HTML差异比较器
html_diff = difflib.HtmlDiff()
html = html_diff.make_file(lines1, lines2,
context=True,
numlines=3)
return html
# 保存为HTML文件
html_result = generate_html_diff(text_a, text_b)
with open('diff_report.html', 'w', encoding='utf-8') as f:
f.write(html_result)
使用difflib.SequenceMatcher进行精确比较
import difflib
def detailed_diff(text1, text2):
"""详细比对文本差异"""
# 创建SequenceMatcher对象
matcher = difflib.SequenceMatcher(None, text1, text2)
# 获取操作码(增删改)
for tag, i1, i2, j1, j2 in matcher.get_opcodes():
if tag == 'equal':
print(f"相同: [{i1}:{i2}] -> [{j1}:{j2}]")
elif tag == 'insert':
print(f"新增: [{i1}:{i2}] -> [{j1}:{j2}]: {text2[j1:j2]}")
elif tag == 'delete':
print(f"删除: [{i1}:{i2}]: {text1[i1:i2]} -> [{j1}:{j2}]")
elif tag == 'replace':
print(f"替换: [{i1}:{i2}]: {text1[i1:i2]} -> [{j1}:{j2}]: {text2[j1:j2]}")
# 更细粒度的字符级别比较
def char_level_diff(text1, text2):
"""字符级别的差异比较"""
import difflib
matcher = difflib.SequenceMatcher(None, text1, text2)
result = []
for tag, i1, i2, j1, j2 in matcher.get_opcodes():
if tag == 'equal':
result.append(text1[i1:i2])
elif tag == 'insert':
result.append(f'[+{text2[j1:j2]}]')
elif tag == 'delete':
result.append(f'[-{text1[i1:i2]}]')
elif tag == 'replace':
result.append(f'[-{text1[i1:i2]}+{text2[j1:j2]}]')
return ''.join(result)
使用外部工具(subprocess调用)
import subprocess
import tempfile
import os
def diff_with_tool(text1, text2, tool='diff'):
"""使用外部差异工具"""
# 创建临时文件
with tempfile.NamedTemporaryFile(mode='w', delete=False) as f1:
f1.write(text1)
temp1 = f1.name
with tempfile.NamedTemporaryFile(mode='w', delete=False) as f2:
f2.write(text2)
temp2 = f2.name
try:
# 调用外部diff命令
if tool == 'diff':
result = subprocess.run(['diff', temp1, temp2],
capture_output=True, text=True)
elif tool == 'diff-u':
result = subprocess.run(['diff', '-u', temp1, temp2],
capture_output=True, text=True)
elif tool == 'wdiff':
result = subprocess.run(['wdiff', temp1, temp2],
capture_output=True, text=True)
return result.stdout
finally:
# 清理临时文件
os.unlink(temp1)
os.unlink(temp2)
# 使用示例
diff_result = diff_with_tool(text_a, text_b, 'diff-u')
print(diff_result)
使用第三方库:deepdiff
pip install deepdiff
from deepdiff import DeepDiff
import json
def compare_structured_text(text1, text2):
"""比较结构化文本(如JSON)"""
# 如果是JSON
try:
obj1 = json.loads(text1)
obj2 = json.loads(text2)
diff = DeepDiff(obj1, obj2, verbose_level=2)
return diff.to_json(indent=2)
except:
return "非JSON格式,请使用其他方法"
# 示例
json_a = '{"name": "张三", "age": 30, "city": "北京"}'
json_b = '{"name": "张三", "age": 31, "city": "上海"}'
result = compare_structured_text(json_a, json_b)
print(result)
实用工具函数:文件对比
import difflib
import os
def compare_files(file1, file2, output_format='text'):
"""对比两个文件的差异"""
# 读取文件
with open(file1, 'r', encoding='utf-8') as f:
text1 = f.read()
with open(file2, 'r', encoding='utf-8') as f:
text2 = f.read()
if output_format == 'text':
# 文本格式
differ = difflib.Differ()
diff = list(differ.compare(text1.splitlines(), text2.splitlines()))
return '\n'.join(diff)
elif output_format == 'html':
# HTML格式
html_diff = difflib.HtmlDiff()
return html_diff.make_file(text1.splitlines(), text2.splitlines())
elif output_format == 'unified':
# 统一格式
return '\n'.join(difflib.unified_diff(
text1.splitlines(), text2.splitlines(),
fromfile=os.path.basename(file1),
tofile=os.path.basename(file2)
))
# 使用示例
result = compare_files('file1.txt', 'file2.txt', 'unified')
print(result)
命令行脚本版本
#!/usr/bin/env python3
# diff_compare.py
import sys
import difflib
import argparse
def main():
parser = argparse.ArgumentParser(description='文本差异比较工具')
parser.add_argument('file1', help='第一个文件')
parser.add_argument('file2', help='第二个文件')
parser.add_argument('-f', '--format', choices=['text', 'html', 'unified'],
default='text', help='输出格式')
parser.add_argument('-o', '--output', help='输出文件路径')
args = parser.parse_args()
# 读取文件
with open(args.file1, 'r', encoding='utf-8') as f:
text1 = f.read()
with open(args.file2, 'r', encoding='utf-8') as f:
text2 = f.read()
lines1 = text1.splitlines()
lines2 = text2.splitlines()
# 生成差异
if args.format == 'html':
result = difflib.HtmlDiff().make_file(lines1, lines2)
elif args.format == 'unified':
result = '\n'.join(difflib.unified_diff(lines1, lines2))
else:
result = '\n'.join(difflib.Differ().compare(lines1, lines2))
# 输出
if args.output:
with open(args.output, 'w', encoding='utf-8') as f:
f.write(result)
else:
print(result)
if __name__ == '__main__':
main()
使用方式:
python diff_compare.py file1.txt file2.txt -f unified
最佳实践建议
-
根据场景选择方法:
- 简单文本对比:
difflib.Differ() - 版本控制风格:
unified_diff() - 可视化展示:HTML格式
- 结构化数据:
deepdiff
- 简单文本对比:
-
性能优化:
- 大文件使用流式处理
- 必要时使用快速算法(如hash比较)
-
编码处理:
- 始终指定正确的编码
- 处理不同换行符(\r\n vs \n)
这些方法可以覆盖大部分文本差异比较的需求,需要根据具体使用场景选择最合适的方式。