Emacs - регулярные выражения в Лиспе нужно экранировать дважды - почему? - PullRequest
23 голосов
/ 12 февраля 2009

Я играл с emacs lisp, и я хотел написать небольшую функцию для поиска и замены регулярного выражения. У меня было чертовски много времени, чтобы заставить регулярное выражение работать правильно, потому что я не понимал, что все специальные символы должны быть дважды экранированы при написании кода lisp (но не при интерактивном использовании query-replace-regexp!).

Так, например, интерактивно используя query-replace-regexp, вы можете использовать

^\(.*\)[\t]-.*$

но при написании кода elisp вам нужно дважды экранировать все так:

^\\(.*\\)[\t]-.*$  

Я наконец нашел ссылку на это в статье Стива Йегге , но мне было интересно, кто-нибудь знает, почему это так?

Ответы [ 4 ]

21 голосов
/ 12 февраля 2009

Это потому, что вам нужно избегать обратной косой черты в строках. Если вы не избежите обратной косой черты \( в строке, она окажется просто (

18 голосов
/ 12 февраля 2009

У вас уже есть ответ, но встроенный помощник для создания регулярных выражений внутри Emacs перестраивается.

M-x re-builder
9 голосов
/ 12 февраля 2009

scottfrazier является правильным, один escape анализируется при чтении строки, другой анализируется при создании регулярного выражения. Это довольно легко запомнить, но это может стать болью, особенно когда вы пытаетесь сопоставить буквальную обратную косую черту «\». В конечном итоге вам придется делать это четыре раза «\\\\», потому что вы должны использовать двойную косую черту, чтобы совпадать с косой чертой как при разборе начальной строки, так и при разборе регулярного выражения.

И когда вы пишете в Stack Overflow об этой проблеме, вы должны использовать 8 слешей , потому что уценка также использует слеш для escape-символа.

8 голосов
/ 12 февраля 2009

FWIW, emacs-lisp-mode будет обозначать специальные выражения (например, \\( и \\) для вас. Затем вы можете изменить лица, чтобы быть что-то, что выделяется.

(Это font-lock-regexp-grouping-construct и font-lock-regexp-grouping-backslash)

...