Javascript экранирование всех символов

Наборы и диапазоны [. ]

Несколько символов или символьных классов в квадратных скобках […] означают «искать любой символ из заданных».

Наборы

Для примера, [eao] означает любой из 3-х символов: ‘a’ , ‘e’ или ‘o’ .

Наборы могут использоваться в регулярных выражениях вместе с обычными символами, например:

// найти [т или х], после которых идёт "оп" alert( "Топ хоп".match(/[тх]оп/gi) ); // "Топ", "хоп"

Обратите внимание, что в наборе несколько символов, но в результате он соответствует ровно одному символу.

Так что этот пример не даёт совпадений:

alert( "Вуаля".match(/В[уа]ля/) ); // null, нет совпадений // ищет "В", затем [у или а], потом "ля" // а в строке В, потом у, потом а

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

Диапазоны

Ещё квадратные скобки могут содержать диапазоны символов.

К примеру, [a-z] соответствует символу в диапазоне от a до z , или 5 – цифра от 0 до 5 .

В приведённом ниже примере мы ищем «x» , за которым следуют две цифры или буквы от A до F :

alert( "Exception 0xAF".match(/x[0-9A-F][0-9A-F]/g) ); // xAF

Здесь в [0-9A-F] сразу два диапазона: ищется символ, который либо цифра от 0 до 9 , либо буква от A до F .

Если мы хотим найти буквы и в верхнем и в нижнем регистре, то мы можем добавить ещё диапазон a-f : [0-9A-Fa-f] . Или поставить у регулярного выражения флаг i .

Также мы можем использовать символьные классы внутри […] .

Например, если мы хотим найти «символ слова» \w или дефис — , то набор будет: [\w-] .

Можем использовать и несколько классов вместе, например [\s\d] означает «пробельный символ или цифра».

Символьные классы – не более чем сокращение для наборов символов.

  • \d – то же самое, что и 5 ,
  • \w – то же самое, что и [a-zA-Z0-9_] ,
  • \s – то же самое, что и [\t\n\v\f\r ] , плюс несколько редких пробельных символов Юникода.

Пример: многоязычный аналог \w

Так как символьный класс \w является всего лишь сокращением для [a-zA-Z0-9_] , он не найдёт китайские иероглифы, кириллические буквы и т.п.

Давайте сделаем более универсальный шаблон, который ищет символы, используемые в словах, для любого языка. Это очень легко с Юникод-свойствами: [\p\p\p\p\p] .

Расшифруем его. По аналогии с классом \w , мы делаем свой набор, который включает в себя символы со следующими Юникодными свойствами:

  • Alphabetic ( Alpha ) – для букв,
  • Mark ( M ) – для акцентов,
  • Decimal_Number ( Nd ) – для цифр,
  • Connector_Punctuation ( Pc ) – для символа подчёркивания ‘_’ и подобных ему,
  • Join_Control ( Join_C ) – два специальных кода 200c и 200d , используемые в лигатурах, например, арабских.
let regexp = /[\p\p\p\p\p]/gu; let str = `Hi 你好 12`; // найдены все буквы и цифры alert( str.match(regexp) ); // H,i,你,好,1,2

Конечно, этот шаблон можно адаптировать: добавить Юникодные свойства или убрать. Более подробно о них было рассказано в главе Юникод: флаг «u» и класс \p .

Поддержка Юникодных свойств p была добавлена в Edge и Firefox относительно недавно. Если нужно реализовать поддержку p для устаревших версий этих браузеров, можно использовать библиотеку XRegExp.

Или же использовать диапазоны символов в интересующем нас языке, например [а-я] для кириллицы.

Исключающие диапазоны

Помимо обычных диапазонов, есть «исключающие» диапазоны, которые выглядят как [^…] .

Они обозначаются символом каретки ^ в начале диапазона и соответствуют любому символу за исключением заданных.

  • [^aeyo] – любой символ, за исключением ‘a’ , ‘e’ , ‘y’ или ‘o’ .
  • [^0-9] – любой символ, за исключением цифры, то же, что и \D .
  • [^\s] – любой непробельный символ, то же, что и \S .

Пример ниже ищет любые символы, кроме латинских букв, цифр и пробелов:

alert( "alice15@gmail.com".match(/[^\d\sA-Z]/gi) ); // @ и .

Экранирование внутри […]

Обычно, когда мы хотим найти специальный символ, нам нужно экранировать его, например \. . А если нам нужна обратная косая черта, тогда используем \\ , т.п.

В квадратных скобках большинство специальных символов можно использовать без экранирования:

  • Символы . + ( ) не нужно экранировать никогда.
  • Тире — не надо экранировать в начале или в конце (где оно не задаёт диапазон).
  • Символ каретки ^ нужно экранировать только в начале (где он означает исключение).
  • Закрывающую квадратную скобку ] , если нужен именно такой символ, экранировать нужно.

Другими словами, разрешены без экранирования все специальные символы, кроме случаев, когда они означают что-то особое в наборах.

Точка . внутри квадратных скобок – просто точка. Шаблон [.,] будет искать один из символов: точку или запятую.

В приведённом ниже примере регулярное выражение [-().^+] ищет один из символов -().^+ :

// Нет необходимости в экранировании let regexp = /[-().^+]/g; alert( "1 + 2 - 3".match(regexp) ); // Совпадения +, -

…Впрочем, если вы решите экранировать «на всякий случай», то не будет никакого вреда:

// Экранирование всех возможных символов let regexp = /[\-\(\)\.\^\+]/g; alert( "1 + 2 - 3".match(regexp) ); // также работает: +, -

Наборы и флаг «u»

Если в наборе есть суррогатные пары, для корректной работы обязательно нужен флаг u .

Например, давайте попробуем найти шаблон [𝒳𝒴] в строке 𝒳 :

alert( '𝒳'.match(/[𝒳𝒴]/) ); // покажет странный символ, что-то типа [?] // (поиск был произведён неправильно, вернулась только половина символа)

Результат неверный, потому что по умолчанию регулярные выражения «не знают» о существовании суррогатных пар.

Движок регулярных выражений думает, что [𝒳𝒴] – это не два, а четыре символа:

  1. левая половина от 𝒳 (1) ,
  2. правая половина от 𝒳 (2) ,
  3. левая половина от 𝒴 (3) ,
  4. правая половина от 𝒴 (4) .

Мы даже можем вывести их коды:

То есть в нашем примере выше ищется и выводится только левая половина от 𝒳 .

Если добавить флаг u , то всё будет в порядке:

Аналогичная ситуация произойдёт при попытке искать диапазон: [𝒳-𝒴] .

Если мы забудем флаг u , то можем нечаянно получить ошибку:

'𝒳'.match(/[𝒳-𝒴]/); // Error: Invalid regular expression

Причина в том, что без флага u суррогатные пары воспринимаются как два символа, так что [𝒳-𝒴] воспринимается как [-] (каждая суррогатная пара заменена на коды). Теперь уже отлично видно, что диапазон 56499-55349 некорректен: его левая граница больше правой, это и есть формальная причина ошибки.

При использовании флага u шаблон будет работать правильно:

// поищем символы от 𝒳 до 𝒵 alert( '𝒴'.match(/[𝒳-𝒵]/u) ); // 𝒴

Задачи

Java[^script]

У нас есть регулярное выражение /Java[^script]/ .

Найдёт ли оно что-нибудь в строке Java ? А в строке JavaScript ?

Ответы: нет, да.

    Нет, т.к. в строке Java нет каких-либо совпадений, потому что [^script] означает «любой символ, кроме заданных». Таким образом, регулярное выражение ищет «Java» , за которым следует один такой символ, но после конца строки нет символов.

alert( "Java".match(/Java[^script]/) ); // null

Источник

Экранирование, специальные символы

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

Есть и другие специальные символы, которые имеют особое значение в регулярном выражении. Они используются для более сложных поисковых конструкций. Вот полный перечень этих символов: [ ] \ ^ $ . | ? * + ( ) .

Не надо пытаться запомнить этот список: мы разберёмся с каждым из них по отдельности, и таким образом вы выучите их «автоматически».

Экранирование символов

Допустим, мы хотим найти буквально точку. Не «любой символ», а именно точку.

Чтобы использовать специальный символ как обычный, добавьте к нему обратную косую черту: \. .

Это называется «экранирование символа».

alert( "Глава 5.1".match(/\d\.\d/) ); // 5.1 (совпадение!) alert( "Глава 511".match(/\d\.\d/) ); // null ("\." - ищет обычную точку)

Круглые скобки также являются специальными символами, поэтому, если нам нужно использовать именно их, нужно указать \( . В приведённом ниже примере ищется строка «g()» :

alert( "function g()".match(/g\(\)/) ); // "g()"

Если мы ищем обратную косую черту \ , это специальный символ как в обычных строках, так и в регулярных выражениях, поэтому мы должны удвоить её.

Косая черта

Символ косой черты ‘/’ , так называемый «слэш», не является специальным символом, но в JavaScript он используется для открытия и закрытия регулярного выражения: /. шаблон. / , поэтому мы должны экранировать его.

Вот как выглядит поиск самой косой черты ‘/’ :

С другой стороны, если мы не используем короткую запись /. / , а создаём регулярное выражение, используя new RegExp , тогда нам не нужно экранировать косую черту:

alert( "/".match(new RegExp("/")) ); // находит /

new RegExp

Если мы создаём регулярное выражение с помощью new RegExp , то нам не нужно учитывать / , но нужно другое экранирование.

Например, такой поиск не работает:

let regexp = new RegExp("\d\.\d"); alert( "Глава 5.1".match(regexp) ); // null

Аналогичный поиск в примере выше с /\d\.\d/ вполне работал, почему же не работает new RegExp(«\d\.\d») ?

Причина в том, что символы обратной косой черты «съедаются» строкой. Как вы помните, обычные строки имеют свои специальные символы, такие как \n , и для экранирования используется обратная косая черта.

Вот как воспринимается строка «\d.\d»:

Строковые кавычки «съедают» символы обратной косой черты для себя, например:

  • \n – становится символом перевода строки,
  • \u1234 – становится символом Юникода с указанным номером,
  • …А когда нет особого значения: как например для \d или \z , обратная косая черта просто удаляется.

Таким образом, new RegExp получает строку без обратной косой черты. Вот почему поиск не работает!

Чтобы исправить это, нам нужно удвоить обратную косую черту, потому что строковые кавычки превращают \\ в \ :

let regStr = "\\d\\.\\d"; alert(regStr); // \d\.\d (теперь правильно) let regexp = new RegExp(regStr); alert( "Глава 5.1".match(regexp) ); // 5.1

Итого

  • Для поиска специальных символов [ ] \ ^ $ . | ? * + ( ) , нам нужно добавить перед ними \ («экранировать их»).
  • Нам также нужно экранировать / , если мы используем /. / (но не new RegExp ).
  • При передаче строки в new RegExp нужно удваивать обратную косую черту: \\ для экранирования специальных символов, потому что строковые кавычки «съедят» одну черту.

Источник

Читайте также:  Пример клиент серверного приложения python
Оцените статью