2013-04-11 2 views
2

Я читаю документацию для Python's difllib. Согласно документации каждый Отличаются дельта дает последовательностьPython Difflib - Как получить SDIF-последовательности с «Change» Op

Code Meaning 
'- ' line unique to sequence 1 
'+ ' line unique to sequence 2 
' ' line common to both sequences 
'? ' line not present in either input sequence 

Но что об операции «Change»? Как получить инструкцию «c», аналогичную результатам в Perl's sdiff?

ответ

1

Показать этот скрипт.

sdiff.py @ hungrysnake.net

http://hungrysnake.net/doc/software__sdiff_py.html

SDiff в Perl (алгоритм :: Diff) не думайте о "Matching скорости", но sdiff.py питона думать об этом. =)

У меня есть 2 текстовых файла.

$ cat text1.txt 
aaaaaa 
bbbbbb 
cccccc 
dddddd 
eeeeee 
ffffff 

$ cat text2.txt 
aaaaaa 
bbbbbb 
xxxxxxx 
ccccccy 
zzzzzzz 
eeeeee 
ffffff 

я бок о бок дифф командой SDiff или SDiff в Perl (алгоритм :: Diff).

$ sdiff text1.txt text2.txt 
aaaaaa   aaaaaa 
bbbbbb   bbbbbb 
cccccc  | xxxxxxx 
dddddd  | ccccccy 
      > zzzzzzz 
eeeeee   eeeeee 
ffffff   ffffff 

SDiff не думаю о "скорости Matching" = (

Я получил его sdiff.py

$ sdiff.py text1.txt text2.txt 
--- text1.txt (utf-8) 
+++ text2.txt (utf-8) 
1|aaaaaa    1|aaaaaa 
2|bbbbbb    2|bbbbbb 
    |   >  3|xxxxxxx 
3|cccccc  |  4|ccccccy 
4|dddddd  <  | 
    |   >  5|zzzzzzz 
5|eeeeee    6|eeeeee 
6|ffffff    7|ffffff 

[  ]  |  + 
[ <- ]  3|cccccc 
[ -> ]  4|ccccccy 

Sdiff.py думать о "скорости Matching" =)

Мне нужен результат sdiff.py. не так ли?

1

Нет прямого 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.

0

Не знаю, что такое операция «Перемена» в Perl. Если он похож на выходе PHP DIFF, я решить мою проблему с этим кодом:

def sdiffer(s1, s2): 
    differ = difflib.Differ() 
    diffs = list(differ.compare(s1, s2)) 

    i = 0 
    sdiffs = [] 
    length = len(diffs) 
    sequence = 0 
    while i < length: 
     line = diffs[i][2:] 
     if diffs[i].startswith(' '): 
      sequence +=1 
      sdiffs.append((sequence,'u', line)) 

     elif diffs[i].startswith('+ '): 
      sequence +=1 
      sdiffs.append((sequence,'+', line)) 

     elif diffs[i].startswith('- '): 
      sequence +=1 
      sdiffs.append((sequence,'-',diffs[i][2:])) 
      if i+1 < length and diffs[i+1].startswith('? '): 
       if diffs[i+3].startswith('?') and i+3 < length : # case 2 
        sequence +=1 
        sdiffs.append((sequence,'+',diffs[i+2][2:])) 
        i+=3 
       elif diffs[i+2].startswith('?') and i+2 < length: # case 3 
        sequence +=1 
        sdiffs.append((sequence,'+',diffs[i+2][2:])) 
        i+=2 
      elif diffs[i+1].startswith('+ ') and i+2<length and diffs[i+2].startswith('? '): # case 1 
       sequence +=1 
       sdiffs.append((sequence,'+', diffs[i+1][2:])) 
       i += 2 
      else: # the line is deleted and inserted new line # case 4 
       sequence +=1 
       sdiffs.append((sequence,'+', diffs[i+1][2:])) 
       i+=1 
     i += 1 
    return sdiffs 

Спасибо @ Sнаđошƒаӽ для вашего кода.

 Смежные вопросы

  • Нет связанных вопросов^_^