Dlaczego niektóre polecenia wyrażenia regularnego mają przeciwne interpretacje „\” z różnymi znakami?

10

Weźmy na przykład to polecenie:

find . -regex ".*\.\(cpp\|h\)"

To znajdzie wszystkie pliki .h i .cpp w twoim katalogu. Znak kropki „.” w wyrażeniach regularnych zwykle oznacza „dowolny znak”. Aby dopasować go tylko do rzeczywistego okresu, musisz uciec z niego, używając znaku odwrotnego ukośnika „\”.

W takim przypadku, mając znak o specjalnym znaczeniu, musisz uciec z niego, aby uzyskać rzeczywisty znak, który reprezentuje.

Teraz weź nawias i pasek „lub”, będące odpowiednio znakami „(”, „)” i „|”. Mają także specjalne znaczenie, używane do grupowania wyrażeń regularnych. Jednak, aby uzyskać specjalne znaczenie, znaki muszą być poprzedzone odwrotnym ukośnikiem! Bez ukośnika znaki mają znaczenie, które reprezentuje.

Dlaczego jest '.' traktowane inaczej niż „(”, „)” i „|”?

Cory Klein
źródło

Odpowiedzi:

12

Odpowiedź brzmi „tylko dlatego”. Istnieje cała masa różnych składni wyrażeń regularnych i chociaż mają one podobny wygląd i zwykle podstawy są takie same, różnią się szczegółami.

Historycznie każde narzędzie miało swoją nową implementację, robiąc wszystko, co autor pomyślał najlepiej. Istnieje równowaga między tworzeniem postaci specjalnych z ucieczką i bez ucieczki - zbyt wiele postaci, które są „naturalnie wyjątkowe”, a ty ostatecznie musisz uciec od nich, aby się z nimi dopasować; lub odwrotnie, w końcu potrzebujesz kilku ucieczek, aby użyć wspólnej składni wyrażeń regularnych, takich jak () grupowanie. I wszyscy, którzy piszą program, zdecydowali, jak to zrobić, w oparciu o potrzeby tego, co ich program pasuje, na podstawie tego, co według nich było właściwym podejściem, i na podstawie fazy księżyca.

Istnieje próba standaryzacji z POSIX, która definiuje „ podstawowe wyrażenia regularne ” i „ rozszerzone wyrażenia regularne ”. Niesamowicie, działają one względem siebie nawzajem \- czasem , ale nie z doskonałą konsekwencją.

Wyrażenia regularne Perla stały się kolejnym standardem defacto z dwóch powodów: po pierwsze, są bardzo elastyczne i potężne, a po drugie, są całkiem rozsądne , z konwencjami takimi jak „\ zawsze ucieka przed znakami niealfanumerycznymi”.

GNU Find ma -regextypeopcję, w której możesz zmienić używaną składnię wyrażeń regularnych. Niestety „perl” nie jest opcją, przynajmniej w wersji find, którą posiadam. (Domyślnie, co nie jest zaskoczeniem z GNU, „emacs”, i ta składnia jest tutaj udokumentowana ).

mattdm
źródło