Нет прямого c
как код в difflib, чтобы показать измененные строки, как в sdiff Perl, о котором вы говорили. Но вы можете сделать это легко. В дельтах difflib «измененные строки» также имеют '- '
, но в отличие от фактически удаленных строк следующая строка в дельта помечена '? '
, чтобы означать, что строка в предыдущем индексе дельта «изменена», а не удален. Другая цель этой линии в дельте состоит в том, что она действует как «руководство» относительно того, где изменения находятся в строке.
Таким образом, если линия в дельте помечается '- '
, то есть четыре различных случая в зависимости от следующих нескольких линий дельты:
Случай 1: Линия модифицируется вставки некоторые символы
- The good bad
+ The good the bad
? ++++
Случай 2: линия модифицируется удаления некоторые символы
- The good the bad
? ----
+ The good bad
Случай 3: Линия модифицируется стиранию и вставив и/или замены некоторые символы:
- The good the bad and ugly
? ^^ ----
+ The g00d bad and the ugly
? ^^ ++++
Case 4: Линия удалена
- The good the bad and the ugly
+ Our ratio is less than 0.75!
Как вы можете видеть, строки, помеченные '? '
, показывают, где именно производится какая модификация.
Обратите внимание, что difflib считает, что строка удаляется, если значение ratio()
между двумя сравниваемыми линиями составляет менее 0,75. Это значение, которое я узнал по некоторым тестам.
Таким образом, чтобы сделать линию измененной, вы можете это сделать. Это вернет и переформатирование с измененными линиями, помеченных с кодом «с», и неизмененными строками, помеченные как «у», так же, как в SDiff в Perl:
def sdiffer(s1, s2):
differ = difflib.Differ()
diffs = list(differ.compare(s1, s2))
i = 0
sdiffs = []
length = len(diffs)
while i < length:
line = diffs[i][2:]
if diffs[i].startswith(' '):
sdiffs.append(('u', line))
elif diffs[i].startswith('+ '):
sdiffs.append(('+', line))
elif diffs[i].startswith('- '):
if i+1 < length and diffs[i+1].startswith('? '): # then diffs[i+2] starts with ('+ '), obviously
sdiffs.append(('c', line))
i += 3 if i + 3 < length and diffs[i + 3].startswith('? ') else 2
elif diffs[i+1].startswith('+ ') and i+2<length and diffs[i+2].startswith('? '):
sdiffs.append(('c', line))
i += 2
else:
sdiffs.append(('-', line))
i += 1
return sdiffs
Надеется, что это помогает.
P.S.: Это старый вопрос, поэтому я не уверен, насколько хорошо мои усилия будут присуждены. :-(
Я просто не мог ответить на этот вопрос, поскольку в последнее время я немного работал с difflib.