difflib 标准库详解:Python 文本对比的利器

06-27 1742阅读

🍀 前言

博客地址:

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

          difflib 标准库详解:Python 文本对比的利器

          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)
          

          💖 欢迎关注我的公众号

          difflib 标准库详解:Python 文本对比的利器

VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]