Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 按单词匹配更改,而不是按字符匹配_Python_String_Python 3.x_Diff_Difflib - Fatal编程技术网

Python 按单词匹配更改,而不是按字符匹配

Python 按单词匹配更改,而不是按字符匹配,python,string,python-3.x,diff,difflib,Python,String,Python 3.x,Diff,Difflib,我正在使用difflib的SequenceMatcher来获取操作码(),然后用css突出显示更改,以创建某种webdiff 首先,我设置了 Min Delta ,所以我认为如果整个字符串中只有3个或更多个字符不同,则两个字符串是不同的( deltaΔ/CODE)是指一个真实的、遇到的delta,它总结了所有字符的变化): matcher=SequenceMatcher(源代码、差异代码) 最小增量=3 增量=0 对于matcher.get_操作码()中的标记i1、i2、j1、j2: 如果标记=

我正在使用
difflib
SequenceMatcher
获取操作码()
,然后用
css
突出显示更改,以创建某种web
diff

首先,我设置了<代码> Min Delta ,所以我认为如果整个字符串中只有3个或更多个字符不同,则两个字符串是不同的(<代码> deltaΔ/CODE)是指一个真实的、遇到的delta,它总结了所有字符的变化):

matcher=SequenceMatcher(源代码、差异代码)
最小增量=3
增量=0
对于matcher.get_操作码()中的标记i1、i2、j1、j2:
如果标记==“相等”:
继续#这里没有要捕获的内容
elif标记==“删除”:
如果源字符串[i1:i2].isspace():
继续#对空格不可知
其他:
delta+=(i2-i1)#删除i2-i1字符
elif标记==“替换”:
如果源字符串[i1:i2].isspace()或差异字符串[j1:j2].isspace():
继续#对空格不可知
其他:
增量+=(i2-i1)#替换i2-i1字符
elif标记==“插入”:
如果差异[j1:j2].isspace():
继续#对空格不可知
其他:
增量+=(j2-j1)#插入j2-j1字符
如果(增量>最小增量)否则为False,则返回值=True
这有助于我确定两个字符串是否真的不同。效率不是很高,但我认为没有比这更好的了

然后,我以相同的方式为两个字符串之间的差异着色:

匹配器中标记i1、i2、j1、j2的
获取操作码()
如果标记==“相等”:
#忙碌的字符串,插入到s和彩色
elif标记==“删除”:
# ...
返回值=旧字符串,新字符串
结果看起来很难看(蓝色表示已替换,绿色表示新,红色表示已删除,不表示相等):

所以发生这种情况是因为
SequenceMatcher
匹配每个字符。但是我想让它匹配每一个单词(可能还有它们周围的空格),或者更吸引人的东西,因为正如你在截图上看到的,第一本书实际上被移动到了第四个位置

在我看来,可以使用
SequenceMatcher
isjunk
autojunk
参数来做一些事情,但我不知道如何编写
lambda
以达到我的目的

因此,我有两个问题:

  • 可以用文字来匹配吗?是否可以使用
    get_opcodes()
    SequenceMatcher
    ?如果没有,可以用什么来代替

  • 好的,这是一个必然结果,但不管怎样:如果可以通过单词匹配,那么我可以使用
    minu delta
    摆脱肮脏的黑客行为,并且只要至少有一个单词不同,就返回
    True
    ,对吗


  • SequenceMatcher
    可以接受
    str
    列表作为输入

    您可以先将输入拆分为单词,然后使用
    SequenceMatcher
    帮助您区分单词。然后,你的彩色差异将是由文字,而不是由字符

    您还可以按直线、书本或线段进行区分。您只需要准备一个函数,该函数可以将整个文章字符串预处理为所需的diff块

    例如:

    • 要按行区分-您可能可以使用
      splitlines()
    • 按书本区分-您可能可以实现一个函数,去掉
      1.
      2.
    • 要按段区分-您可以这样插入API
      ([book_1,author_1,year_1,book_2,author_2,…],[book_1,author_1,year_1,book_2,author_2,…)
      。然后你的颜色将被分段

    。。。你没有想到,
    True if delta>min_delta else False
    与简单的
    delta>min_delta
    完全相同吗?说得好!当我在编写代码时,这只是一种为我自己添加更多清晰性的方法。我通常在之后重构代码,以消除不必要的冗长和内联一些操作。这次我忘了在一个示例中这样做。请不要滥用内联代码格式来突出显示不是代码的内容(例如类/模块/函数名、小代码示例等)或按字面意思编写的内容(例如,应完全按照显示内容编写的唯一标识符)。要强调其他类型的内容,请使用斜体(*斜体*)或粗体(**粗体**)。
    >>> def my_get_opcodes(a, b):
    ...     s = SequenceMatcher(None, a, b)
    ...     for tag, i1, i2, j1, j2 in s.get_opcodes():
    ...         print('{:7}   a[{}:{}] --> b[{}:{}] {!r:>8} --> {!r}'.format(
    ...             tag, i1, i2, j1, j2, a[i1:i2], b[j1:j2]))
    ... 
    
    >>> my_get_opcodes("qabxcd", "abycdf")
    delete    a[0:1] --> b[0:0]      'q' --> ''
    equal     a[1:3] --> b[0:2]     'ab' --> 'ab'
    replace   a[3:4] --> b[2:3]      'x' --> 'y'
    equal     a[4:6] --> b[3:5]     'cd' --> 'cd'
    insert    a[6:6] --> b[5:6]       '' --> 'f'
    
    # This is the bad result you currently have.
    >>> my_get_opcodes("one two three\n", "ore tree emu\n")
    equal     a[0:1] --> b[0:1]      'o' --> 'o'
    replace   a[1:2] --> b[1:2]      'n' --> 'r'
    equal     a[2:5] --> b[2:5]    'e t' --> 'e t'
    delete    a[5:10] --> b[5:5]  'wo th' --> ''
    equal     a[10:13] --> b[5:8]    'ree' --> 'ree'
    insert    a[13:13] --> b[8:12]       '' --> ' emu'
    equal     a[13:14] --> b[12:13]     '\n' --> '\n'
    
    >>> my_get_opcodes("one two three\n".split(), "ore tree emu\n".split())
    replace   a[0:3] --> b[0:3] ['one', 'two', 'three'] --> ['ore', 'tree', 'emu']
    
    # This may be the result you want.
    >>> my_get_opcodes("one two emily three ha\n".split(), "ore tree emily emu haha\n".split())
    replace   a[0:2] --> b[0:2] ['one', 'two'] --> ['ore', 'tree']
    equal     a[2:3] --> b[2:3] ['emily'] --> ['emily']
    replace   a[3:5] --> b[3:5] ['three', 'ha'] --> ['emu', 'haha']
    
    # A more complicated example exhibiting all four kinds of opcodes.
    >>> my_get_opcodes("one two emily three yo right end\n".split(), "ore tree emily emu haha yo yes right\n".split())
    replace   a[0:2] --> b[0:2] ['one', 'two'] --> ['ore', 'tree']
    equal     a[2:3] --> b[2:3] ['emily'] --> ['emily']
    replace   a[3:4] --> b[3:5] ['three'] --> ['emu', 'haha']
    equal     a[4:5] --> b[5:6]   ['yo'] --> ['yo']
    insert    a[5:5] --> b[6:7]       [] --> ['yes']
    equal     a[5:6] --> b[7:8] ['right'] --> ['right']
    delete    a[6:7] --> b[8:8]  ['end'] --> []