Porównanie dokumentów
Porównanie dokumentów
Ten przewodnik pokazuje, jak porównać dwa ciągi tekstu i wygenerować sekwencję edycji między nimi przy użyciu silnika tekstowego diff Aspose.PDF FOSS dla .NET. Punktem wejścia dla tego modelu porównania jest DiffOperation, pojedyncza edycja oznaczona Operation (Equal, Delete, lub Insert), wraz z DiffUtils klasą pomocniczą służącą do znajdowania wspólnego tekstu oraz składania diffu z powrotem do tekstu źródłowego i docelowego. Oddzielny etap optymalizacji, opisany w Optymalizacji Diff, kanonizuje surowy wynik diff wygenerowany w ten sposób przed jego renderowaniem lub zastosowaniem.
Model diffu: Operacja i DiffOperation
Operation jest wyliczeniem, które klasyfikuje każdą edycję w diffie: Equal oznacza ciąg tekstu, który jest niezmieniony, Delete oznacza ciąg usunięty ze źródła, a Insert oznacza ciąg dodany w docelowym. DiffOperation łączy wartość Operation z Text, do którego się odnosi, i implementuje IEquatable<DiffOperation>, aby dwie edycje mogły być porównywane pod kątem równości.
using Aspose.Pdf.Comparison.Diff;
// A single edit consists of an Operation and the run of text it applies to.
var unchanged = new DiffOperation(Operation.Equal, "Aspose.PDF ");
var removed = new DiffOperation(Operation.Delete, "for .NET Framework");
var added = new DiffOperation(Operation.Insert, "FOSS for .NET");
Console.WriteLine(unchanged.Operation); // Equal
Console.WriteLine(added.Text); // "FOSS for .NET"Wyszukiwanie wspólnego tekstu przy użyciu DiffUtils
DiffUtils jest statyczną klasą pomocniczą używaną przez silnik diff do znajdowania wspólnego prefiksu i sufiksu współdzielonych przez dwa ciągi znaków przed difowaniem różniącej się środkowej części. FindCommonStartParts znajduje wspólny prefiks, a FindCommonEndParts znajduje wspólny sufiks; przeciążenie FindCommonEndParts przyjmuje startIndex, aby wyszukiwanie sufiksu mogło być ograniczone do tekstu następującego po już zlokalizowanym prefiksie.
string original = "The quick brown fox";
string revised = "The quick red fox jumps";
var commonStart = DiffUtils.FindCommonStartParts(original, revised);
var commonEnd = DiffUtils.FindCommonEndParts(original, revised);Ponowne składanie tekstu z diffu
Gdy różnica jest wyrażona jako ciąg wartości DiffOperation, DiffUtils może odtworzyć obie strony porównania: AssemblySourceText odtwarza oryginalny tekst z uruchomień Equal i Delete, a AssemblyDestinationText odtwarza zmieniony tekst z uruchomień Equal i Insert.
using System.Collections.Generic;
var diffs = new List<DiffOperation>
{
new DiffOperation(Operation.Equal, "The quick "),
new DiffOperation(Operation.Delete, "brown"),
new DiffOperation(Operation.Insert, "red"),
new DiffOperation(Operation.Equal, " fox")
};
string sourceText = DiffUtils.AssemblySourceText(diffs);
string destinationText = DiffUtils.AssemblyDestinationText(diffs);
Console.WriteLine(sourceText); // "The quick brown fox"
Console.WriteLine(destinationText); // "The quick red fox"Porównywanie i raportowanie edycji
DiffOperation nadpisuje Equals, GetHashCode i ToString, dzięki czemu edycje można porównywać pod kątem równości lub zapisywać do logów i wyników testów bez dodatkowego kodu konwersji.
var a = new DiffOperation(Operation.Equal, "PDF");
var b = new DiffOperation(Operation.Equal, "PDF");
bool same = a.Equals(b); // true - same Operation and Text
Console.WriteLine(a.ToString());Wskazówki i najlepsze praktyki
DiffOperationjest niezmienny i implementujeIEquatable<DiffOperation>— użyjEquals, aby porównać dwie edycje zamiast sprawdzać równość referencji.- Najpierw znajdź wspólny prefiks przy użyciu
FindCommonStartParts, a następnie przekaż jego długość do przeciążeniastartIndexwFindCommonEndParts, aby uniknąć podwójnego liczenia krótkiego wspólnego prefiksu jako części sufiksu. - Użyj
AssemblySourceTextiAssemblyDestinationText, aby zweryfikować, że ciąg wartościDiffOperationprzechodzi w obie strony do dokładnego oryginalnego i zmienionego tekstu, zanim użyjesz go w innym miejscu. - Traktuj uruchomienia
Operation.Equaljako operacje bez efektu przy renderowaniu wizualnej różnicy i podświetlaj tylko uruchomieniaDeleteiInsert. - Ten silnik porównuje tekst, a nie dokumenty bezpośrednio — wyodrębnij tekst, który chcesz porównać (na przykład z strony lub dokumentu) przed utworzeniem różnicy.
Typowe problemy
| Problem | Przyczyna | Napraw |
|---|---|---|
AssemblySourceText / AssemblyDestinationText wynik nie pasuje do oryginałów | Lista diffs jest niekompletna lub jej pozycje DiffOperation są w nieprawidłowej kolejności | Dołącz wszystkie edycje w kolejności, w której pierwotnie wystąpiły |
FindCommonEndParts zwraca nieoczekiwany wynik dla krótkich, podobnych ciągów | Wyszukiwanie wspólnego przyrostka zachodzi na tekst już dopasowany przez FindCommonStartParts | Przekaż długość zwróconą przez FindCommonStartParts jako argument startIndex |
Equals zwraca false dla edycji, które wyglądają identycznie | Wartości Text różnią się spacjami lub wielkością liter | Znormalizuj tekst (przytnij / zignoruj wielkość liter) przed tworzeniem wartości DiffOperation, które zamierzasz porównać |
| Wynik diff jest hałaśliwy lub niepotrzebnie fragmentaryczny | Surowe ciągi DiffOperation nie są jeszcze kanonikalizowane | Przeprowadź ciąg przez etap optymalizacji opisany w Optymalizacja Diff |
FAQ
Co porównuje silnik Diff?
Porównuje fragmenty tekstu i generuje ciąg wartości DiffOperation opisujących edycje — niezmieniony, usunięty lub wstawiony tekst — potrzebne do przekształcenia jednego łańcucha w drugi.
Jakie typy edycji obsługuje Operation?
Trzy: Equal dla niezmienionego tekstu, Delete dla tekstu usuniętego ze źródła oraz Insert dla tekstu dodanego w miejscu docelowym.
Jak sprawdzić, czy dwie edycje są takie same?
Wywołaj Equals na instancji DiffOperation, lub porównaj bezpośrednio jej właściwości Operation i Text.
Czy mogę odzyskać oryginalny i zmodyfikowany tekst z diffu?
Tak — przekaż listę wartości DiffOperation do DiffUtils.AssemblySourceText dla tekstu oryginalnego oraz DiffUtils.AssemblyDestinationText dla tekstu zmienionego.
Czy ta strona obejmuje scalanie lub czyszczenie diffu?
Nie — kanonikalizacja surowego diffu (scalanie sąsiadujących fragmentów, przesuwanie edycji przez równości) jest opisane osobno w Optymalizacja diffu.
API Reference Podsumowanie
| Klasa / Metoda | Opis |
|---|---|
Operation | Enum klasyfikujące edycję jako Equal, Delete lub Insert |
DiffOperation | Pojedyncza edycja: Operation połączony z Text, do którego ma zastosowanie |
DiffOperation.Operation | Wartość Operation dla tej edycji |
DiffOperation.Text | Fragment tekstu, którego dotyczy ta edycja |
DiffOperation.Equals | Porównuje dwie edycje pod kątem równości według Operation i Text |
DiffOperation.ToString | Renderuje edycję jako ciąg znaków do logowania lub wyświetlania |
DiffUtils | Statyczna klasa pomocnicza z narzędziami do różnicowania tekstu |
DiffUtils.FindCommonStartParts | Znajduje wspólny prefiks dwóch ciągów znaków |
DiffUtils.FindCommonEndParts | Znajduje wspólny sufiks dwóch ciągów znaków, opcjonalnie zaczynając od indeksu |
DiffUtils.AssemblySourceText | Składa ponownie oryginalny tekst z listy wartości DiffOperation |
DiffUtils.AssemblyDestinationText | Składa ponownie zrewidowany tekst z listy wartości DiffOperation |