Il n'y a pas de code direct c
dans difflib pour afficher les lignes modifiées comme dans le sdiff de Perl dont vous avez parlé. Mais vous pouvez en faire un facilement. Dans le delta de difflib, les "lignes modifiées" ont également '- '
, mais contrairement aux lignes effacées, la ligne suivante dans le delta est marquée '? '
pour indiquer que la ligne dans l'index précédent du delta est "modifiée", et non supprimé Un autre objectif de cette ligne dans le delta est qu'il sert de «guide» quant à l'endroit où les changements sont dans la ligne.
Ainsi, si une ligne dans le delta est marqué avec '- '
, alors il y a quatre cas différents selon les quelques lignes du delta:
Cas 1: La ligne modifiée par insertion certains caractères
- The good bad
+ The good the bad
? ++++
cas 2: La ligne est modifiée par la suppressioncertains caractères
- The good the bad
? ----
+ The good bad
Cas 3: la ligne est modifiée par la suppression et l'insertion et/ou remplaçant certains caractères:
- The good the bad and ugly
? ^^ ----
+ The g00d bad and the ugly
? ^^ ++++
Cas 4: la ligne est supprimé
- The good the bad and the ugly
+ Our ratio is less than 0.75!
Comme vous pouvez le constater, les lignes marquées '? '
indiquent exactement le type de modification effectué.
Notez que difflib considère qu'une ligne est supprimée si la valeur de ratio()
entre les deux lignes comparées est inférieure à 0,75. C'est une valeur que j'ai découverte grâce à certains tests.
Donc, pour déduire une ligne comme modifiée, vous pouvez le faire. Cela renverra les diffs avec des lignes modifiées taggés avec 'c', le code et les lignes inchangées dans la catégorie 'u', tout comme dans le sdiff de 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
Hope it helps.
P.S.: C'est une vieille question, donc je ne sais pas si mes efforts seront récompensés. :-(
Je n'ai pas pu m'empêcher de répondre à cette question, car j'ai travaillé un peu avec difflib ces derniers temps.