difflib 标准库详解:Python 文本对比的利器
🍀 前言
博客地址:
- CSDN:https://blog.csdn.net/powerbiubiu
👋 简介
difflib 模块是 Python 标准库中的一个模块,用于比较文本之间的差异。它提供了一些函数和类,可以帮助你找到两个字符串或列表之间的相似性和差异性。
📖 正文
1 匹配最大相似内容
语法:difflib.get_close_matches(word, possibilities, n=3, cutoff=0.6)
参数说明:
- word:要匹配的目标字符串;
- possibilities:包含可能匹配项的列表;
- n:可选参数,指定返回的最大匹配项数,默认为 3;
- cutoff:可选参数,表示匹配度的阈值,只返回匹配度大于等于该阈值的项,默认为 0.6。
函数会返回一个列表,其中包含了与目标字符串最相似的项。它会基于 difflib 库中的模糊匹配算法,找到给定字符串在候选列表中的可能匹配项。
import difflib colors = ['red', 'blue', 'green', 'yellow', 'black', 'white'] wrong_color = "grren" result = difflib.get_close_matches(wrong_color, colors) print(result) # ['green']
2 两个文本之间的差异
2.1 context_diff
语法:difflib.context_diff(a, b, fromfile='', tofile='', fromfiledate='', tofiledate='', n=3, lineterm='\n')
参数说明:
- a:第一个文本内容(通常为列表形式,每行作为一个元素);
- b:第二个文本内容(同样通常为列表形式);
- fromfile:可选参数,用于指定第一个文件名;
- tofile:可选参数,用于指定第二个文件名;
- fromfiledate:可选参数,用于指定第一个文件的日期;
- tofiledate:可选参数,用于指定第二个文件的日期;
- n:可选参数,用于指定上下文的行数;
- lineterm:可选参数,用于指定行终止符,默认为 \n。
函数会返回一个生成器,可以逐行输出表示差异的文本。该差异文本遵循标准的 Unix 上下文 diff 格式,显示出两个文本之间的差异以及周围的上下文信息。
import difflib text1 = ['Hello', 'World', 'Python'] text2 = ['Hello', 'There', 'Python'] diff = difflib.context_diff(text1, text2, fromfile='file1.txt', tofile='file2.txt') for line in diff: print(line) # *** file1.txt # --- file2.txt # *************** # *** 1,3 **** # Hello # ! World # Python # --- 1,3 ---- # Hello # ! There # Python
2.2 nidff
语法:difflib.ndiff(a, b)
参数说明:
- a:第一个文本内容(通常为列表形式,每行作为一个元素);
- b:第二个文本内容(同样通常为列表形式)。
这个函数会返回一个生成器,可以逐行输出表示差异的文本。相比较 context_diff,ndiff 会以更加紧凑的格式展示每行文本的差异,使用特定的标记符号来表示新增、删除和修改等操作。
import difflib text1 = ['Hello', 'World', 'Python'] text2 = ['Hello', 'There', 'Python'] diff = difflib.ndiff(text1, text2) for line in diff: print(line) # Hello # - World # + There # Python
在使用difflib.ndiff进行对比,结果中的符号意义如下:
符号 含义 ‘-’ 包含在第一个系列行中,但不包含第二个。 ‘+’ 包含在第二个系列行中,但不包含第一个。 ’ ’ 两个系列行一致。 ‘?’ 存在增量差异。 ‘^’ 存在差异字符。 3 生成html对比结果
通过difflib.HtmlDiff()实现将对比结果生成html页面进行展示。
import difflib text1 = '''1. Beautiful is better than ugly. 2. Explicit is better than implicit. 3. Simple is better than complex. 4. Complex is better than complicated. '''.splitlines(keepends=True) text2 = '''1. Beautiful is better than ugly. 3. Simple is better than complex. 4. Complicated is better than complex. 5. Flat is better than nested. '''.splitlines(keepends=True) html_diff = difflib.HtmlDiff() html_output = html_diff.make_file(text1, text2) with open('diff_output.html', 'w') as f: f.write(html_output)
4 工具类封装
import difflib import os.path import time from typing import List class DiffContent: @classmethod def _read_file(cls, file_path: str) -> List[str]: """ 读取文件内容 :param file_path: 文件绝对路径 :return: 列表 """ try: with open(file_path, "rb") as f: # 二进制方式读取文件内容,并转换为str类型 lines = f.read().decode('utf-8') # 按行进行分割 text = lines.splitlines() return text except Exception as e: print("ERROR: {}".format(str(e))) @classmethod def compare_diff_by_file(cls, file_1: str, file_2: str, save_path: str = '') -> None: """ 对比文件内如差异,并输出html文件,文件名命名:compare_file1name_file2name.html :param file_1:文件1 :param file_2:文件2 :param save_path:生成html文件路径(默认值为空,生成到当前目录) :return: """ # 获取文件内容 file_1_content = cls._read_file(file_1) file_2_content = cls._read_file(file_2) # 创建比较器 compare = difflib.HtmlDiff() res = compare.make_file(file_1_content, file_2_content) # 获取输出html文件的绝对路径 file_1_name = os.path.basename(file_1).split('.')[0] file_2_name = os.path.basename(file_2).split('.')[0] if save_path: out_file = '{}/compare_{}_{}.html'.format(save_path, file_1_name, file_2_name) else: out_file = 'compare_{}_{}.html'.format(file_1_name, file_2_name) with open(out_file, 'w') as fp: fp.writelines(res) @classmethod def compare_text(cls, src_text: str, target_text: str, save_path: str = '') -> None: """ 比较给定的2个字符串,并输出html文件 :param src_text: :param target_text: :param save_path:生成html文件路径(默认值为空,生成到当前目录) :return: """ compare = difflib.HtmlDiff() compare_result = compare.make_file(src_text, target_text) if save_path: out_file = '{}/compare{}.html'.format(save_path, str(time.time()).split('.')[0]) else: out_file = 'compare{}.html'.format(str(time.time()).split('.')[0]) with open(out_file, 'w') as f: f.writelines(compare_result)
💖 欢迎关注我的公众号
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。