【问题标题】:python 3, differences between two stringspython 3,两个字符串之间的差异
【发布时间】:2018-02-12 00:15:57
【问题描述】:

我想在一个列表中记录两个字符串的差异位置(以删除它们)...最好记录每个部分的最高分隔点,因为这些区域将具有动态内容。

比较这些

总字符数 178。两个独特的部分

t1 = 'WhereTisthetotalnumberofght5y5wsjhhhhjhkmhm Thethreemethodsthatreturntheratioofmatchingtototalcharacterscangivedifferentresultsduetodifferinglevelsofapxxxxxxxproximation,although'

总字符数 211。两个独特的部分

t2 = 'WhereTisthetotalnumberofdofodfgjnjndfgu><rgregw><sssssuguyguiygis>gggs<GS,Gs Thethreemethodsthatreturntheratioofmatchingtototalcharacterscangivedifferentrexxxxxxxsultsduetodifferinglevelsofapproximation,although'

我知道 difflib 可以做到这一点,但输出很糟糕。

我想(在列表中)存储字符位置,最好是较大的分隔值。

图案位置

t1 = 'WhereTisthetotalnumberof  24  ght5y5wsjhhhhjhkmhm  43  Thethreemethodsthatreturntheratioofmatchingtototalcharacterscangivedifferentresultsduetodifferinglevelsofap  151  xxxxxxx  158  proximation,although'
t2 = 'WhereTisthetotalnumberof  24  dofodfgjnjndfgu><rgregw><sssssuguyguiygis>gggs<GS,Gs  76  Thethreemethodsthatreturntheratioofmatchingtototalcharacterscangivedifferentre  155  xxxxxxx  162  sultsduetodifferinglevelsofapproximation,although'

输出:

output list = [24, 76, 151, 162]

更新

回复@Olivier

由 *** 分隔的所有 Y 的位置

t1
WhereTisthetotalnumberofght5***y***5wsjhhhhjhkmhm Thethreemethodsthatreturntheratioofmatchingtototalcharacterscangivedifferentresultsduetodifferinglevelsofapxxxxxxxproximation,although

t2 WhereTisthetotalnumberofdofodfgjnjndfgu><rgregw><sssssugu***y***gui***y***gis>gggs<GS,Gs Thethreemethodsthatreturntheratioofmatchingtototalcharacterscangivedifferentrexxxxxxxsultsduetodifferinglevelsofapproximation,although

ma​​tcher.get_matching_blocks()之后的输出string = ''.join([t1[a:a+n] for a, _, n in blocks])

WhereTisthetotalnumberof***y*** Thethreemethodsthatreturntheratioofmatchingtototalcharacterscangivedifferentresultsduetodifferinglevelsofapproximation,although

【问题讨论】:

  • 除了它的减法和加法值放在字符旁边。它只处理非常慢的列表。这些字符串会很大。 2000 多个字符。但是欢迎使用 difflib 示例进行基准测试。谢谢!

标签: string python-3.x difflib


【解决方案1】:

使用difflib 可能是您最好的选择,因为您不太可能提出比它提供的算法更有效的解决方案。你想要的是使用SequenceMatcher.get_matching_blocks。这是它会根据doc 输出的内容。

返回描述匹配子序列的三元组列表。每三倍 形式为(i, j, n),表示a[i:i+n] == b[j:j+n]。这 三元组在 ij 中单调递增。

这是一种方法,您可以使用它来重建删除了增量的字符串。

from difflib import SequenceMatcher

x = "abc_def"
y = "abc--ef"

matcher = SequenceMatcher(None, x, y)
blocks = matcher.get_matching_blocks()

# blocks: [Match(a=0, b=0, size=4), Match(a=5, b=5, size=2), Match(a=7, b=7, size=0)]

string = ''.join([x[a:a+n] for a, _, n in blocks])

# string: "abcef"

编辑:还有人指出,在你有两个这样的字符串的情况下。

t1 = 'WordWordaayaaWordWord'
t2 = 'WordWordbbbybWordWord'

那么上面的代码将返回'WordWordyWordWord。这是因为get_matching_blocks 将捕获出现在预期块之间的两个字符串中的'y'。解决此问题的方法是按长度过滤返回的块。

string = ''.join([x[a:a+n] for a, _, n in blocks if n > 1])

如果您想对返回的块进行更复杂的分析,您还可以执行以下操作。

def block_filter(substring):
    """Outputs True if the substring is to be merged, False otherwise"""
    ...


string = ''.join([x[a:a+n] for a, _, n in blocks if block_filter(x[a:a+n])])

【讨论】:

  • 谢谢你,看起来很有希望,给我一天左右的时间,我会回到这个帖子。这是估计吗? 字符串返回WhereTisthetotalnumberofy Thethreemethodsthatreturntheratioofmatchingtototalcharacterscangivedifferentresultsduetodifferinglevelsofapproximation,although部分ofyThe不正确
  • 您能重新格式化您之前的评论吗?我不太明白你的意思。
  • 在第一部分 WhereTisthetotalnumberof 之后有一个字符 y .. 我不知道为什么它在那里。
  • t1t2 在您预期的第一个和第二个块之间都有一个 'y'。所以正如预期的那样get_matching_blocks 接了它。如果您在问题中提供有关预期行为的其他详细信息,则可以修复它。例如,我们可以过滤掉匹配少于一定字符数的块。
  • 我已经为这个问题添加了一个回复帖子,希望能更好地解释
猜你喜欢
  • 2012-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-08
  • 2010-11-28
相关资源
最近更新 更多