Я использую difflib
«s SequenceMatcher
к get_opcodes()
и чем выделить изменения с css
, чтобы создать какое-то веб-diff
.соответствий, слова, а не символы
Во-первых, я поставил min_delta
, так что я считаю две строки различны, если только 3 или более символов всей строки различаются, один за другим (delta
означает реальное, встречается дельту, которая суммирует все изменения один-символов) :
matcher = SequenceMatcher(source_str, diff_str)
min_delta = 3
delta = 0
for tag, i1, i2, j1, j2 in matcher.get_opcodes():
if tag == "equal":
continue # nothing to capture here
elif tag == "delete":
if source_str[i1:i2].isspace():
continue # be whitespace-agnostic
else:
delta += (i2 - i1) # delete i2-i1 chars
elif tag == "replace":
if source_str[i1:i2].isspace() or diff_str[j1:j2].isspace():
continue # be whitespace-agnostic
else:
delta += (i2 - i1) # replace i2-i1 chars
elif tag == "insert":
if diff_str[j1:j2].isspace():
continue # be whitespace-agnostic
else:
delta += (j2 - j1) # insert j2-j1 chars
return_value = True if (delta > min_delta) else False
Это помогает мне определить, действительно ли две строки отличаются друг от друга. Не очень эффективно, но я не думал, что лучше.
Затем я раскрасить различия между двумя строками таким же образом:
for tag, i1, i2, j1, j2 in matcher.get_opcodes():
if tag == "equal":
# bustling with strings, inserting them in <span>s and colorizing
elif tag == "delete":
# ...
return_value = old_string, new_string
И результат выглядит довольно уродливо (синий для замены зеленый новый и красный для удаления, ничего для равных):
Так, это происходит потому, что SequenceMatcher
спичек каждый символ. Но я хочу, чтобы оно соответствовало каждому слову вместо этого (и, вероятно, пробелам вокруг них), или что-то еще более привлекательное, потому что, как вы можете видеть на скриншоте, первая книга действительно перемещена на четвертую позицию.
Мне кажется, что что-то может быть сделано с isjunk
и autojunk
параметров SequenceMatcher
, но я не могу понять, как писать lambda
с для моих целей.
Таким образом, у меня есть два вопросы:
Можно ли соответствовать словами? Можно ли использовать
get_opcodes()
иSequenceMatcher
? Если нет, что можно использовать вместо этого?Хорошо, это скорее следствие, но все же: если соответствие слов можно, то я могу избавиться от грязных писак с
min_delta
и вернутьсяTrue
как только по крайней мере одно отличающимся словом, верно?
... не возникло для вас, что 'True if delta> min_delta else False' * точно так же *, как просто' delta> min_delta'? – Bakuriu
Хорошая точка! Когда я пишу код, это просто способ добавить больше ясности для себя. Я обычно реорганизую код после удаления ненужной многословности и встраивания некоторых операций. На этот раз я забыл сделать это на примере. – light2yellow