Простой скрипт для получения различий между строк на python
, это полезно при создании тестов. Существует стандартная библиотека difflib
для этих целей, но я написал для неё более читаемый аналог.
Стандартный вариант
st1 = """/media/user/dd19b13d-bd85-46bb-8db9-5b8f6cf7a825/MyProject/PycharmProject/testfull_pack/venvs/bin/python/scratch_34.py"""
st2 = """/media/user/dd19b13d-bd85-46bb-8et9-5b8f6cf7a825/MyProject/PycharmProjects/testfull_pack/venvs/bin/python/scratch_34.py"""
rs = ''.join(list(difflib.unified_diff(st1, st2)))print(rs)
Ответ:
---
+++
@@ -30,8 +30,8 @@
b - 8-d-b+e+t 9 - 5@@ -71,6 +71,7 @@
e c t+s / t e
Мой скрипт
class colors:
green = '\x1b[32m'
reset = '\x1b[0m'
red = '\x1b[31m'
black = '\x1b[30m'
yellow = '\x1b[33m'
blue = '\x1b[34m'
magenta = '\x1b[35m'
cyan = '\x1b[36m'
white = '\x1b[37m'
bg_red = '\x1b[41m'
bg_green = '\x1b[42m'
def diff_string(str1: str, str2: str):
_max = max([len(str1), len(str2)])
_len_str1 = len(str1)
_len_str2 = len(str2)
_res1 = ''
_res2 = ''
for _symbol in range(_max):
if _symbol < _len_str1 and _symbol < _len_str2:
if str1[_symbol] == str2[_symbol]:
_res1 += '{1}{0}{2}'.format(str1[_symbol], colors.green, colors.reset)
_res2 += '{1}{0}{2}'.format(str2[_symbol], colors.green, colors.reset)
else:
_res1 += '{1}{0}{2}'.format(str1[_symbol], colors.red, colors.reset)
_res2 += '{1}{0}{2}'.format(str2[_symbol], colors.red, colors.reset)
continue
elif _symbol < _len_str1:
_res1 += '{1}{0}{2}'.format(str1[_symbol], colors.bg_green, colors.reset)
_res2 += '{1}{0}{2}'.format(' ', colors.bg_red, colors.reset)
elif _symbol < _len_str2:
_res1 += '{1}{0}{2}'.format(' ', colors.bg_red, colors.reset)
_res2 += '{1}{0}{2}'.format(str2[_symbol], colors.bg_green, colors.reset)
else:
raise ValueError
return _res1, _res2
if __name__ == '__main__':
st1 = """/media/user/dd19b13d-bd85-46bb-8db9-5b8f6cf7a825/MyProject/PycharmProject/testfull_pack/venvs/bin/python/scratch_34.py"""
st2 = """/media/user/dd19b13d-bd85-46bb-8et9-5b8f6cf7a825/MyProject/PycharmProjects/testfull_pack/venvs/bin/python/scratch_34.py"""
# Пример 1
rst1, rst2 = diff_string(st1, st2)
print(f'str1:::\n{rst1}')
print(f'str2:::\n{rst2}')
Ответ:
Комментарии (7)
andreymal
27.03.2022 00:24+2Не очень понял, что мешает просто сделать обёртку для difflib с желаемым оформлением:
def diff_string(str1: str, str2: str): rst1 = rst2 = "" for op, i1, i2, j1, j2 in difflib.SequenceMatcher(a=str1, b=str2).get_opcodes(): if op in ("delete", "replace"): rst1 += colors.red + str1[i1:i2] + colors.reset if op in ("insert", "replace"): rst2 += colors.green + str2[j1:j2] + colors.reset if op == "equal": rst1 += str1[i1:i2] rst2 += str2[j1:j2] return rst1, rst2
Но даже если нужно тупое посимвольное сравнение, то вариант из поста можно записать чуть менее громоздко (возможно, можно придумать ещё компактнее, но у меня на ночь глядя мозги не очень варят):
def diff_string(str1: str, str2: str): l1 = len(str1) l2 = len(str2) rst1 = rst2 = "" for a, b in zip(str1, str2): color = colors.red if a != b else colors.green rst1 += color + a + colors.reset rst2 += color + b + colors.reset if l1 > l2: rst1 += colors.bg_red + str1[l2:] + colors.reset rst2 += colors.bg_red + " " * (l1 - l2) + colors.reset elif l1 < l2: rst1 += colors.bg_red + " " * (l2 - l1) + colors.reset rst2 += colors.bg_red + str2[l1:] + colors.reset return rst1, rst2
SergeiMinaev
27.03.2022 04:30Можно узнать, зачем у вас все переменные в diff_string() начинаются с подчёркивания?
unsignedchar
27.03.2022 10:21+2Выглядит так, будто автор не разобрался, как работает стандартный инструмент, и поэтому запилил свой собственный, аналогов которому нет ;)
Vishnu
28.03.2022 09:26Наглядный пример того, что сначала нужно выучить родной язык, а только потом браться за чужой.
различий между строк
Это на каком языке?!!
petrov_engineer
У вас функция неправильно отрабатывает, в строке изменилась подстрока
PycharmProject
наPycharmProjects
, но эта разница подсветилась как-будто изменился весь конец строки.