Dlaczego wyrażenia regularne utworzone za pomocą konstruktora wyrażeń regularnych używają składni innej niż interaktywne wyrażenia regularne?

26

Tak więc, używając konstruktora wyrażeń regularnych (re-builder Mx), znajdowanie linii kończących się na \ wymaga „\\ $”, podczas gdy wyszukiwanie i zamiana na wyrażenie regularne zajmuje tylko „\ $”. Oczekiwałem, że konstruktor wyrażeń regularnych będzie budował wyrażenia bezpośrednio użyteczne, więc co tłumaczy tę różnicę?

użytkownik2699
źródło
6
Buduje wyrażenia bezpośrednio użyteczne w kodzie.
abo-abo,
1
@ abo-abo To była odpowiedź, której szukałem, nie zdawałem sobie sprawy, że istnieje różnica między tym, co można wykorzystać w kodzie, a tym, co jest możliwe w interfejsie użytkownika. Wydaje się sprzeczne z intuicją, że przebudowujący używa składni kodów, a instrukcja nie mówi, ale to wyjaśnia różnicę.
user2699,
2
Aby uczynić konstruktora wyrażeń regularnych bardziej przydatnym do tworzenia interaktywnych wyszukiwań, zajrzyj na stronę wiki emBack ReBuildera , zwłaszcza reb-query-replacedefinicję funkcji.
dfeich,

Odpowiedzi:

29

W rzeczywistości istnieją cztery różne re-builderopcje składni i możesz się między nimi przełączaćC-cTAB

Dwa dotyczą kompilatorów regularnych typu sexp rxi sregex(ponieważ ten pierwszy jest bardziej wszechstronny i prawie całkowicie kompatybilny ze składnią, możesz naprawdę zignorować sregex, chyba że pracujesz ze starym kodem, który go używał).

Pozostałe dwie opcje składni to read(domyślna) i string(której składni używasz interaktywnie).

readSkładnia jest składnia „kod” - czyli jak rozpoznawane przez czytnik lisp - w którym wchodzi się do wyrażenia regularnego jak na składni czytać ciągi :

C-hig (elisp) Syntax for Strings RET

stringSkładnia (które zawsze uważane za nazwę niepotrzebnie mylące w tym kontekście) jest składnia wyrażeń regularnych ciąg , który już został odczytany , a zatem nie ma żadnego z charakterem wymagane uwalnianych podczas pisania ciąg. To znaczy, że jest to rzeczywista składnia wyrażeń regularnych, taka sama, jakiej używasz, gdy Emacs monituje Cię interaktywnie.

Jeśli chcesz domyślnie używać składni łańcuchów, dodaj następujące pliki do pliku init lub użyj M-x customize-option RET reb-re-syntax RET

(setq reb-re-syntax 'string)

Zauważ, że podczas edycji wyrażenia regularnego możesz przełączać się między składnią odczytu i składnią ciągów, bez utraty danych. Możesz także przełączyć się z formularzy sexp na składnię read / string (naturalnie; kompilacja sexps do łańcuchów jest tym, do czego służą te biblioteki), ale nie możesz iść w innym kierunku i generować sexp z łańcucha. re-builder pamięta, co to był sexp, więc nie tracisz tej formy po zmianie składni; ale nie zostanie również zaktualizowany, jeśli zmodyfikujesz wyrażenie regularne w innej składni, a następnie zmienisz z powrotem. Krótko mówiąc, jeśli budujesz wyrażenie regularne jako sexp, upewnij się, że edytujesz go tylko przy użyciu tej składni.


Gotcha ze rxwsparciem polega na tym, że faktycznie używa rx-to-stringfunkcji, która nie jest całkiem identyczna z użyciem rxmakra w kodzie. rxakceptuje dowolną liczbę argumentów postaci i traktuje je jako dorozumianą sekwencję , podczas gdy rx-to-stringakceptuje tylko jedną formę, a każda sekwencja najwyższego poziomu musi być jawna za pomocą '(sequence ...)lub równoważna.

Krótko mówiąc, po wprowadzeniu formularza '(...)w programie do przebudowy jest on przetwarzany jako (rx-to-string '(...))i nie(rx ...)

Należy również pamiętać, że niepoprawny formularz może spowodować, re-builderże przestanie on dynamicznie aktualizować dopasowania w powiązanym buforze, nawet po ponownym zatwierdzeniu formularza. C-cC-uDo wiązania reb-force-updatejest przydatna do rozwiązywania takich sytuacji.


Domyślnie wiersz trybu pokazuje „RE Builder” przy użyciu readlub stringskładni oraz „RE Builder Lisp” przy użyciu rxlub sregexskładni, ale wydaje się znacznie bardziej użyteczne określenie konkretnej używanej składni (szczególnie w celu rozróżnienia między readi string).

Jeśli instalujesz delightpakiet z GNU ELPA, możesz użyć następujących poleceń, aby dodać wskaźnik składni do wiersza trybu.

(let ((name '("Regexp[" (:eval (symbol-name reb-re-syntax)) "]")))
  (delight `((reb-mode ,name :major)
             (reb-lisp-mode ,name :major))))

Zmienia to nazwę trybu na „Regexp [czytaj]” w readskładni i podobnie dla pozostałych.

Lub w celu dołączenia podpowiedzi do opisanej powyżej funkcji rxvs, rx-to-stringustaw linię trybu na „Regexp [rx-to-string]” przy użyciu rxskładni:

(let ((name '("Regexp["
              (:eval (symbol-name (if (eq reb-re-syntax 'rx)
                                      'rx-to-string
                                    reb-re-syntax)))
              "]")))
  (delight `((reb-mode ,name :major)
             (reb-lisp-mode ,name :major))))
phils
źródło