Чем объясняется различное обращение со специальными символами в регулярных выражениях?

#javascript #regex

#javascript #регулярное выражение

Вопрос:

Тестирование в Chrome 10 Developer Tools console:

 > str = "t";
  " "
> JSON.stringify(str)
  ""t""
> str.replace(/t/g,"\t")
  "t"
  

Все хорошо. Регулярное выражение смогло воспроизвести часть JSON.stringify поведения и идентифицировать символ табуляции.

Теперь давайте заменим t на b во всем:

 > str = "b";
  ""
> JSON.stringify(str)
  ""b""
> str.replace(/b/g,"\b")
  ""
  

В этом случае replace не удалось найти символ обратного пробела.

Итак, мои уважаемые коллеги по SO, не мог бы кто-нибудь дать мне подсказку и объяснить разницу в поведении?

Ответ №1:

Escape-последовательности в регулярных выражениях не идентичны таковым в строковых литералах. В регулярном выражении b соответствует границе слова. t происходит то же самое в регулярных выражениях и строковых литералах.

В MDC есть довольно хорошее описание этих символов, хотя, конечно, нет ничего лучше, чем обратиться к спецификации.

Комментарии:

1. Это кажется очевидным, когда вы так это формулируете. Следующий вопрос должен быть таким: как мне изменить регулярное выражение, чтобы найти и заменить обратную косую черту в строке JavaScript?

2. @Jim: Повторная escape-последовательность для обратной косой черты такая же, как и в строковом литерале: две обратные косые черты: \. Или, если вы имели в виду обратный пробел , вам пришлось бы либо использовать шестнадцатеричный escape ( x08 ) или Unicode escape ( u0008 ), либо передать строку в RegExp конструктор (чего я рекомендую избегать, это очень быстро приводит к путанице): new RegExp("\b") Это создает строку, содержащую обратную косую черту, за которой следует пробел, который затем передается в RegExp конструктор. RegExp Видит обратную косую черту и обрабатывает следующий символ (пробел) буквально. Вы видите, как это может сбить с толку.

3. Ти Джей, ты звезда.. str.replace(/x08/g,"\b") доставляет товар.