Problem
Nie ma łatwego sposobu na uzyskanie permutacji za pomocą wyrażenia regularnego.
- Permutacja: Uzyskanie słowa („aabc”) w innym porządku, bez zmiany liczby lub rodzaju liter.
- Regex: wyrażenie regularne.
Dla weryfikacji:
- „Permutacje regexów bez powtórzeń” Odpowiedź tworzy kod JavaScript zamiast wyrażenia regularnego, zakładając, że byłoby to prostsze.
- „Jak znaleźć wszystkie permutacje danego słowa w danym tekście” - Odpowiedź również nie używa wyrażeń regularnych.
- „Ponownie dopasuj, aby dopasować wszystkie {1, 2, 3, 4} bez powtórzeń” - w odpowiedzi użyto wyrażeń regularnych, ale nie jest to ani adaptowalne, ani proste.
- Ta odpowiedź twierdzi nawet: „Wyrażenie regularne nie może robić tego, o co prosisz. Nie może generować permutacji z łańcucha” .
Rodzaj rozwiązania, którego szukam
Powinien mieć postać:
- »Aabc« (lub cokolwiek innego, czego można użyć nawiasów otwierających i zamykających)
- (aabc)! (podobny do (abc)? ale z innym symbolem na końcu)
- [aabc]! (podobny do [abc] +, ale z innym symbolem na końcu)
Zalety tych rozwiązań
Oni są:
- łatwy
- dający się przystosować
- wielokrotnego użytku
Dlaczego to powinno istnieć
- Regeksy są sposobem na opisanie gramatyki zwykłego języka. Mają pełną moc, aby być dowolnym językiem.
- Powiedzmy, że zwykłe języki są wystarczająco mocne, aby uzyskać permutacje (dowód poniżej) - dlaczego nie ma łatwego sposobu na wyrażenie tego?
Więc moje pytanie brzmi:
- (Dlaczego) Czy mój dowód jest błędny?
- Jeśli to prawda: dlaczego nie ma łatwego sposobu wyrażenia permutacji?
Dowód
- Wyrażenia regularne są jednym ze sposobów odnotowania gramatyki języka regularnego. Potrafią opisać dowolną gramatykę języków regularnych.
- Innym sposobem na opisanie języków regularnych (które mają skończoną liczbę liter w swoim alfabecie) gramatyka są niedeterministyczne Automaty (o skończonej liczbie stanów).
Mając skończoną liczbę liter, mogę utworzyć ten automat: (Przykład. Formalny: patrz poniżej)
Gramatyka, która akceptuje permutacje „abbc”:
(wypowiedz cyfry na górze, może ktoś wie, jak sprawić, by ta część wyglądała lepiej)
s -> ah¹
s -> bh²
s -> ch³
h¹ -> bh¹¹
h¹ -> ch¹²
h² -> ah¹¹ (brak równoważności literówek!)
h² -> bh²²
h² -> ch²³
h³ -> ah¹²
h³ -> bh²³
h¹¹ -> bc
h¹¹ -> cb
h¹² -> bb
h²² -> ac
h²² -> ca
h²³ -> ab
h²³ -> ba
Bardziej formalne: (przy użyciu automatu stanu skończonego, ale można to również zrobić za pomocą gramatyki)
- Słowo q (o skończonej długości), do którego każda permutacja powinna osiągnąć stan akceptacji.
- X jest skończonym alfabetem.
- Zbiór stanów S zawiera dowolną kolejność liter do długości q. (Więc rozmiar S jest skończony.) Plus jeden stan „dowolnego dłuższego słowa”.
- funkcja przejścia stanu d, która przyjmuje literę i przesuwa się do stanu, który odpowiada teraz czytanej części słowa.
- F jest zbiorem tych stanów, które są dokładnymi permutacjami q.
Możliwe jest więc utworzenie automatu skończonego do akceptowania permutacji danego słowa.
Idąc dalej z dowodem
Udowodniłem, że zwykłe języki mają uprawnienia do sprawdzania permutacji, prawda?
Dlaczego więc nie ma podejścia do osiągnięcia tego za pomocą Regexes? To przydatna funkcjonalność.
^(a()|a()|b()|c()){4}\2\3\4\5$
wydaje się działać (patrz regex101.com/r/9URPpg/4/tests ).Odpowiedzi:
Podstawowe twierdzenia formalnej teorii języka są takie, że wyrażenia regularne, gramatyka regularna, deterministyczne automaty skończone (DFA) i niedeterministyczne automaty skończone (NFA) opisują te same rodzaje języków: mianowicie języki regularne. Fakt, że możemy opisać te języki na tak wiele różnych sposobów, sugeruje, że istnieje coś naturalnego i ważnego w tych językach, w taki sam sposób, w jaki równoważność maszyn Turinga, rachunku lambda i wszelkiego rodzaju innych rzeczy sugeruje, że języki obliczalne są naturalne i ważne. Nie są jedynie artefaktem przypadkowych decyzji podjętych przez pierwotnego odkrywcę.
Załóżmy, że dodać nową regułę tworzenia wyrażeń regularnych: jeśliR jest wyrażenie regularne, wtedy π(R) jest wyrażeniem regularnym, a to pasuje do każdego permutacji każdego łańcucha dopasowane R . Na przykład L(π(abc))={abc,acb,bac,bca,cab,cba} . Problem polega na tym, że łamie to podstawowe równoważniki opisane powyżej. L(π((ab)∗))) jest językiem ciągów, które zawierają taką samą liczbę a s i b s, a to nie jest język regularny. Porównaj to, na przykład, dodając operator negacji lub odwrócenia do wyrażeń regularnych, co nie zmienia klasy akceptowanych języków.
Tak więc, aby odpowiedzieć na pytanie tytułowe, wyrażenia regularne nie mogą dokonywać permutacji i nie dodajemy tej możliwości, ponieważ wtedy wyrażenia regularne nie pasują do języków regularnych. Powiedziawszy to, możliwe jest, że „wyrażenia regularne z permutacjami” byłyby również interesującą klasą języków o wielu różnych charakterystykach.
źródło
!
operatora w praktyce i przypuszczam, że niewiele osób ma, ponieważ jest łatwe do wdrożenia i nie ma rozszerzenia rozszerzonych wyrażeń regularnych. widzieliśmy, że to popiera.Twój „dowód” dotyczył tylko permutacji pojedynczych słów, które są skończonymi językami.
Każdy skończony język jest regularny (np. Po prostu wymieniając wszystkich członków
|
pomiędzy), ale istnieją nieskończone regularne języki (i te są na ogół bardziej interesujące).Gdy tylko otrzymasz wyrażenie regularne (lub gramatykę / automat), które akceptuje nieskończony język (tj. Wyrażenie z
*
operatorem lub automat z pętlą), twoja konstrukcja już nie działa (otrzymujesz nieskończoną gramatykę / automat) ).Odpowiedź Davida Richerby podała przykład zwykłego języka, którego język permutacji nie jest już regularny - wszystkie takie przykłady są nieskończonymi językami.
źródło
W pewnym sensie nie ma zwięzłego sposobu na określenie wszystkich permutacji słowa.
źródło
Dlaczego nie ma sposobu na napisanie „permutacji” w Regexes
Permutacja zwykłego, nieskończonego języka (nieskończona ilość słów) niekoniecznie jest regularna. Dlatego nie można go zapisać jako wyrażenia regularnego.
Dowód
Pomyśl o języku
(ab)*
. (Przykład zainspirowany przez Davida Richerby'ego .) Jedną z jego permutacji jesta*b*
. To nie jest zwykły język. co było do okazania.źródło