首页 > 解决方案 > difflib - 使用 ndiff() 忽略空格差异?

问题描述

我在这里查看了类似问题的一些答案,但我想我仍然不了解工作方式difflib.ndiff()

ndiff特别关注,因为文档暗示,默认情况下,差异将忽略空格更改。

这是一个简单的程序,我希望 Differ 中的行(即,来自 的返回值difflib.ndiff())为空:

import difflib

# a simple set of lines
A_LINES = [
    'Line 1',
    'Line 2',
]

# should be same as A_LINES if whitespace is ignored
B_LINES = [
    '  Line 1',
    '  Line 2',
]

def test_2(a, b):
    # differ = difflib.ndiff(a, b)
    differ = difflib.ndiff(a, b, charjunk=difflib.IS_CHARACTER_JUNK)
    for line in differ:
        print(line)

def main(a_fn, b_fn):
    test_2(A_LINES, B_LINES)


if __name__ == '__main__':
    main()

difflib.IS_CHARACTER_JUNK()似乎只是一个返回andTrue的谓词,否则。无论您是通过显式调用 来调用,还是接受默认值而不提及参数,我都会得到相同的输出:' ''\t'Falsendiff()IS_CHARACTER_JUNKcharjunk

- Line 1
+   Line 1
? ++

- Line 2
+   Line 2
? ++

对于忽略空格的差异,这不是我所期望的输出。考虑到 ndiff 的文档(参见:https ://docs.python.org/3/library/difflib.html ),这对我来说似乎很意外。文档是关闭的、奇怪的还是错误的,还是我只是不理解某些东西?

对于此示例,我将如何调用ndiff()以使“不同”生成器中没有行?

任何帮助更好地理解如何做"ignore whitespace"-type diffs非常感谢。

标签: pythondiffdifflib

解决方案


似乎IS_CHARACTER_JUNK调用了过滤器函数,但对过滤垃圾字符没有任何作用。对我来说似乎是一个错误。Python 3.6 difflib 的行为仍然相同。

我现在可以提出一个可接受的解决方法:从行中删除尾随和前导空格,并将所有重复的空格替换为一个空格。这至少提供了可利用的输出(删除所有空格是不切实际的)。

import difflib
import re

lines1 = ["foo bar ","cat ","nope"]
lines2 = ["foo  bar   ","hello","cat    "]

def prefilter(line):
    return re.sub("\s+"," ",line.strip())

for d in difflib.ndiff([prefilter(x) for x in lines1],[prefilter(x) for x in lines2]):
    print(d)

结果(仅添加/删除的行显示为更改,添加/删除空格的行不显示)

  foo bar
+ hello
  cat
- nope

推荐阅读