2012-05-27 11 views
6

Mam następującą funkcję, która pobiera źródło i zmodyfikowane ciągi i pogrubia zmienione słowa w nim.Znajdowanie różnic między ciągami

def appendBoldChanges(s1, s2): 
    "Adds <b></b> tags to words that are changed" 
    l1 = s1.split(' ') 
    l2 = s2.split(' ') 
    for i, val in enumerate(l1): 
     if l1[i].lower() != l2[i].lower(): 
      s2 = s2.replace(l2[i], "<b>%s</b>" % l2[i]) 

    return s2 
print appendBoldChanges("britney spirs", "britney spears") # returns britney <b>spears</b> 

Współpracuje na łańcuchach o tej samej liczby słów, ale nie liczy się z różnych słów, jak sora iro days i sorairo days.

Jak wziąć pod uwagę ten odstęp?

+0

@mata Możesz rzeczywiście udzielić takiej odpowiedzi. :) – SuperSaiyan

+0

@Thrustmaster - jak sobie życzysz: b – mata

Odpowiedz

21

Można użyć difflib, i zrobić to tak:

from difflib import Differ 

def appendBoldChanges(s1, s2): 
    "Adds <b></b> tags to words that are changed" 
    l1 = s1.split(' ') 
    l2 = s2.split(' ') 
    dif = list(Differ().compare(l1, l2)) 
    return " ".join(['<b>'+i[2:]+'</b>' if i[:1] == '+' else i[2:] for i in dif 
                  if not i[:1] in '-?']) 

print appendBoldChanges("britney spirs", "britney sprears") 
print appendBoldChanges("sora iro days", "sorairo days") 
#Output: 
britney <b>sprears</b> 
<b>sorairo</b> days 
+1

+1 za wspaniały jednolinijkowy. Możesz wyczyścić zwracany ciąg. Wprowadzanie 'appendBoldChanges (" dni sorairo "," dni sora iro ")' powoduje 'sorairo dni, kiedy OP prawdopodobnie potrzebował' sora iro dni'. Prawdziwie Pythonic elegance. – gauden

+0

@gauden - okrzyki;) Pomyślałem, że to nie ma znaczenia, ponieważ wyświetlają to samo. Jeśli jest to problem, to tak, na samym końcu, '.replace ('', ''), będzie naprawą. – fraxel

+0

Jestem pewien, że masz rację :) – gauden

1

małe uaktualnienie tp @fraxel odpowiedź, która zwraca 2 wyjścia - oryginalna i nowa wersja z naniesionymi zmianami. Zmieniam także jedną linijkę na bardziej czytelną wersję, w mojej opinii

def show_diff(text, n_text): 
    seqm = difflib.SequenceMatcher(None, text, n_text) 
    output_orig = [] 
    output_new = [] 
    for opcode, a0, a1, b0, b1 in seqm.get_opcodes(): 
     orig_seq = seqm.a[a0:a1] 
     new_seq = seqm.b[b0:b1] 
     if opcode == 'equal': 
      output_orig.append(orig_seq) 
      output_new.append(orig_seq) 
     elif opcode == 'insert': 
      output_new.append("<font color=green>{}</font>".format(new_seq)) 
     elif opcode == 'delete': 
      output_orig.append("<font color=red>{}</font>".format(orig_seq)) 
     elif opcode == 'replace': 
      output_new.append("<font color=blue>{}</font>".format(new_seq)) 
      output_orig.append("<font color=blue>{}</font>".format(orig_seq)) 
     else: 
      print('Error') 
    return ''.join(output_orig), ''.join(output_new) 
Powiązane problemy