1

我有两个文本。

T0 ID A
T1 ID B
T2 ID C
T4 ID D

T5 ID A
T6 ID E
T7 ID F
T8 ID D

我真的只对比较 ID 序列和字母的差异感兴趣。但是我想在输出中保留每个元素的第一部分,以便以后可以将其用于其他分析,即输出看起来像这样

@-1,2 +1,2
-T2 ID B
-T3 ID C
+T6 ID E
+T7 ID F

做这种差异的最佳方法是什么?理想情况下使用 difflib python 库。

另外,说不是 2 个文本,我有 2 个对象列表,每个对象都有 2 个属性(object.t 返回 T1,object.ID 返回 B),并且我只想对对象列表执行差异标识属性。我可以执行这样的操作吗?也许这应该是一个不同的问题。

谢谢

4

1 回答 1

0

您可以创建str该哈希的子类并进行比较,就好像它仅包含其 ID:

import re

class IdString(str):
    """A string that hashes and compares on its id.

        >>> hash(IdString('XXX ID A XXX')) == hash('A')
        True
        >>> hash(IdString('XXX ID abc XXX')) == hash('abc')
        True
        >>> IdString('XXX ID A XXX') == IdString('YYY ID A YYY')
        True
        >>> IdString('XXX ID A XXX') == IdString('XXX ID B XXX')
        False

    """
    def __new__(cls, *args):
        self = super(IdString, cls).__new__(cls, *args)
        m = re.search(r'\bID (\w+)', self)
        self.id = m.group(1)
        return self

    def __hash__(self):
        return hash(self.id)

    def __eq__(self, other):
        return self.id == other.id

    def __ne__(self, other):
        return self.id != other.id

然后你可以把你的普通字符串变成IdString对象并将它们传递给difflib,如下所示:

from difflib import unified_diff

text1 = '''T0 ID A
T1 ID B
T2 ID C
T4 ID D
'''

text2 = '''T5 ID A
T6 ID E
T7 ID F
T8 ID D
'''

print(''.join(unified_diff(map(IdString, text1.splitlines(True)),
                           map(IdString, text2.splitlines(True)),
                           n=0)))

这几乎产生了您想要的输出:

--- 
+++ 
@@ -2,2 +2,2 @@
-T1 ID B
-T2 ID C
+T6 ID E
+T7 ID F

(您问题中的示例说@-1,2 +1,2,但我无法准确重现,因为我不知道 diff 是什么风格,并且行号在 diff 输出中从 1 开始。)

于 2013-10-03T10:31:26.620 回答