Pasujące symbole wieloznaczne — Matching wildcards

W informatyce algorytm dopasowywania symboli wieloznacznych (znany również jako globbing ) jest przydatny do porównywania ciągów tekstowych, które mogą zawierać składnię symboli wieloznacznych . Typowe zastosowania tych algorytmów obejmują interfejsy wiersza poleceń , np. powłoki Bourne'a lub wiersza poleceń Microsoft Windows lub edytora tekstu lub menedżera plików, a także interfejsy niektórych wyszukiwarek i baz danych. Dopasowywanie symboli wieloznacznych to podzbiór problemu dopasowywania wyrażeń regularnych i ogólnie dopasowywania ciągów .

Problem

Dopasowywanie symboli wieloznacznych testuje wzorzec wieloznaczny p względem ciągu wejściowego s . Wykonuje zakotwiczone dopasowanie, zwraca true tylko wtedy, gdy p pasuje do całości s .

Wzorzec może być oparty na dowolnej powszechnej składni (patrz globbing ), ale programiści Windows zwykle omawiają tylko uproszczoną składnię obsługiwaną przez natywne środowisko wykonawcze C:

  • Nie zdefiniowano znaków ucieczki
  • Symbole wieloznaczne: ?dopasowuje dokładnie jedno wystąpienie dowolnego znaku. *dopasowuje dowolną liczbę (w tym zero) wystąpień dowolnego znaku.

W tym artykule omówiono głównie sformułowanie problemu w systemie Windows, chyba że zaznaczono inaczej.

Definicja

Wyrażony w indeksach liczonych od zera, problem dopasowania symboli wieloznacznych można zdefiniować rekurencyjnie jako:

gdzie m ij jest wynikiem dopasowania wzorca p do tekstu t skróconego odpowiednio przy znakach i i j . Jest to sformułowanie używane przez algorytm Richtera i algorytm Snippets znaleziony w kolekcji Cantatore. Ten opis jest podobny do odległości Levenshteina .

Powiązane problemy

Bezpośrednio powiązane problemy w informatyce obejmują:

  • Dopasowywanie wzorców za pomocą nie przejmuje się ani lukami, wyszukiwaniem niezakotwiczonych ciągów tylko z odpowiednikiem ?zdefiniowanego.
  • Dopasowywanie wzorców za pomocą symboli wieloznacznych, wyszukiwanie niezakotwiczonych ciągów ze zdefiniowanymi odpowiednikami obu symboli wieloznacznych. Ma wykładnicze środowisko wykonawcze, chyba że w dopasowaniu wzorca z elastycznym wariantem symboli wieloznacznych podano ograniczenie długości.

Historia

Wczesne algorytmy dopasowywania symboli wieloznacznych często opierały się na rekurencji , ale technika ta została skrytykowana ze względu na wydajność i niezawodność. W świetle tych rozważań na korzyść zyskały nierekurencyjne algorytmy dopasowywania symboli wieloznacznych.

Wśród algorytmów zarówno rekurencyjnych, jak i nierekurencyjnych, strategie wykonywania operacji dopasowywania wzorców różnią się znacznie, czego dowodem jest różnorodność przykładowych algorytmów, o których mowa poniżej. Techniki opracowywania przypadków testowych i optymalizacji wydajności zostały wyraźnie zastosowane w niektórych algorytmach, szczególnie tych opracowanych przez krytyków algorytmów rekurencyjnych.

Algorytmy rekurencyjne

Rekurencja zwykle ma miejsce *podczas dopasowywania, gdy istnieje więcej sufiksów do dopasowania. Jest to forma wycofywania się , również wykonywana przez niektóre dopasowania wyrażeń regularnych.

  • Rich Salz ' wildmat algorytm (SH jak składni)
  • Algorytm Filipa i algorytm Vignesha Murugesana
  • Algorytm Martina Richtera (identyczny jak Snippets i powiązany z algorytmem 7-zip)
  • Implementacje fnmatch biblioteki C (wsparcie [...]i zestawy znaków wielobajtowych):

Ogólna forma tych algorytmów jest taka sama. W przypadku rekursji algorytm dzieli dane wejściowe na podciągi i uważa, że ​​dopasowanie miało miejsce, gdy JEDEN z podciągów zwraca dodatni wynik. Bo dowild("*X", "abcX")chciwie wzywał dowild("X", "abcX"), dowild("X", "bcX"), dowild("X", "cX")i dowild("X", "X"). Zwykle różnią się one mniej ważnymi rzeczami, takimi jak obsługa funkcji i ważniejszymi czynnikami, takimi jak drobne, ale bardzo skuteczne optymalizacje. Niektóre z nich to:

  • Sygnał ABORT przeciwko nadmiernej rekurencji (Lars Mathiesen 1991). Chociaż poprawne jest naiwne rekursyzowanie przez całą resztę ciągów (wzór i tekst) *i upewnienie się, że JEDEN z podciągów zwraca pozytywne dopasowanie, czas działania staje się wykładniczy dla odrzucenia dopasowania z wieloma *w tekście. Lars Mathiesen zmienia zwrot na trzy klasy, dopasowanie, brak dopasowania i PRZERWIJ (w ogóle niemożliwe dopasowanie w przypadku rekursji gwiazdki). Wartość PRZERWIJ jest zwracana, gdy tekst jest zużywany zbyt wcześnie lub gdy inne dopasowanie gwiazdki nie powiodło się, gwarantując wydajność liniowa w odniesieniu do liczby gwiazdek. (Całkowita złożoność jest dodatkowo kwadratowa do liczby znaków pozostałych do dopasowania.) Wildmatch ABORT w Git/Rsync obejmuje również nieprawidłowe dane wejściowe. Nowy uwildmat INN robi to samo.
  • Zaawansowanie gwiazdką w rekurencji. Ta modyfikacja Wildmatchu jest stosunkowo mniejsza. Dotyczy to sytuacji, gdy rekursja chce dopasować „*X” do „abcX”: gdy po gwiazdki następuje literał „X”, oczywiste jest, że tylko ostatnie porównanie o równych długościach miałoby szansę na uzyskanie dopasowania . Widać to wcześniej w uwildmat w 2000 roku i bardziej pośrednio w fnmatch van Rossuma dla FNM_PATHNAME.

Algorytm Martina Richtera jest wyjątkiem od tego wzorca, chociaż ogólna operacja jest równoważna. Na * powraca do zwiększania jednego z indeksów, zgodnie z dynamicznym programowaniem sformułowania problemu. Stosuje się do niej również technika „PRZERWIJ”. W typowych wzorcach (testowanych przez Cantatore) jest wolniejszy niż implementacje greedy-call.

Algorytmy rekurencyjne są generalnie łatwiejsze do zrozumienia, a po modyfikacji ABORT działają w sposób akceptowalny pod względem złożoności najgorszego przypadku. W przypadku ciągów bez *, dopasowanie rozmiaru liniowego do rozmiaru ciągu zajmuje czas, ponieważ istnieje stała relacja jeden do jednego.

Algorytmy nierekurencyjne

Krytycy algorytmów rekurencyjnych opracowują następujące rozwiązania:

  • Algorytm dopasowywania symboli wieloznacznych Kirka J. Kraussa , używany przez IBM
  • Kolekcja algorytmów dopasowywania symboli wieloznacznych Alessandro Cantatore
  • Iteracyjny matcher Dogana Kurta i wolniejszy matcher NFA.
  • Nieprawidłowy algorytm Silera (nie powiodło się MATCH("da*da*da*", "daaadabadmanda"))

Następujące nie jest:

  • Nieprawidłowy algorytm Jacka Handy'ego (nie powiodło się MATCH("*?", "xx"))

Powyższe funkcje iteracyjne implementują wycofywanie, zapisując stary zestaw wskaźników do wzorca/tekstu i powracając do niego, jeśli dopasowanie się nie powiedzie. Według Kurta, ponieważ potrzebny jest tylko jeden udany mecz, wystarczy zapisać tylko jeden taki zestaw.

Ponadto problem dopasowywania symboli wieloznacznych można przekształcić w dopasowywanie wyrażeń regularnych przy użyciu naiwnego podejścia polegającego na zastępowaniu tekstu . Chociaż nierekurencyjne dopasowania wyrażeń regularnych, takie jak konstrukcja Thompsona, są rzadziej używane w praktyce ze względu na brak obsługi odwołań wstecznych, generalnie dopasowywanie symboli wieloznacznych nie ma podobnie bogatego zestawu funkcji. (W rzeczywistości wiele z powyższych algorytmów obsługuje tylko ?i *.) Implementację Thompsona NFA firmy Russ Cox można lekko zmodyfikować pod kątem takich. Oparty na BDM algorytm nrgrep Gustavo Navarro zapewnia bardziej uproszczoną implementację z naciskiem na wydajne przyrostki. Zobacz także wyrażenia regularne § implementacje .

Zobacz też

Bibliografia