- Операторы
- Управляющие инструкции
- JS Объекты
- Array
- Boolean
- Date
- Error
- Function
- Global
- JSON
- Math
- Number
- Object
- RegExp
- String
- Unicode
- Symbol
- Итераторы и генераторы
- Map и WeakMap
- Set и WeakSet
- Локализация
- браузер BOM
- HTML DOM
- События
- HTML Объекты
- Промисы, async/await
- Сетевые запросы
- Бинарные данные и файлы
- Модули
- Классы
- Разное
Объект RegExp
Регулярные выражения позволяют производить гибкий поиск в строках текста.
Создание
var expr = new RegExp(pattern [, flags]); // полная форма записи var expr = /pattern/flags; // сокращенная форма записи (литеральный формат)
Параметры
- pattern
- Шаблон поиска (текст регулярного выражения).
- flags
- Способы поиска по шаблону:
- g — глобальный поиск (обрабатываются все совпадения с шаблоном поиска);
- i — не различать строчные и заглавные буквы;
- m — многострочный поиск.
- u — включает поддержку Юникода в регулярных выражениях.
Комментарии
Когда регулярное выражение создается при помощи конструктора new RegExp(…), необходимо помнить, что обратные слеши (\) должны экранироваться, например:
var expr = new RegExp('\\w', 'ig');
При использовании литерального формата, этого делать не нужно:
var expr = /\w/gi;
Обе записи эквивалентны. Первый вариант может понадобится, если вам придется генерировать регулярное выражение динамически.
В регулярных выражениях различают следующие виды символов:
Обычные символы
| A..z | английские буквы от A до z, строчные и заглавные |
| 0..9 | цифры |
| { } | фигурные скобки, кроме случаев, когда они составляют группу вида {n,m} (где n и m — числа) и её вариации |
| = | равно |
| < | меньше |
| > | больше |
| - | минус |
| , | запятая |
| и др. |
Специальные символы
| ( ) | круглые скобки |
| [ ] | квадратные скобки |
| \ | обраный слеш |
| . | точка |
| ^ | степень |
| $ | знак доллара |
| | | вертикальная черта |
| ? | вопросительный знак |
| + | плюс. |
Спецсимволы в регулярном выражении
| Символ | Значение |
|---|---|
| \ | Для обычных символов - делает их специальными. Например, выражение /s/ ищет просто символ 's'. А если поставить \ перед s, то /\s/ уже обозначает пробельный символ. И наоборот, если символ специальный, например *, то \ сделает его просто обычным символом "звездочка". Например, /a*/ ищет 0 или больше подряд идущих символов 'a'. Чтобы найти а со звездочкой 'a*' - поставим \ перед спец. символом: /a\*/. |
| ^ | Обозначает начало входных данных. Если установлен флаг многострочного поиска ("m"), то также сработает при начале новой строки. Например, /^A/ не найдет 'A' в "an A", но найдет первое 'A' в "An A." |
| $ | Обозначает конец входных данных. Если установлен флаг многострочного поиска, то также сработает в конце строки. Например, /t$/ не найдет 't' в "eater", но найдет - в "eat". |
| * | Обозначает повторение 0 или более раз. Например, /bo*/ найдет 'boooo' в "A ghost booooed" и 'b' в "A bird warbled", но ничего не найдет в "A goat grunted". |
| + | Обозначает повторение 1 или более раз. Эквивалентно {1,}. Например, /a+/ найдет 'a' в "candy" и все 'a' в "caaaaaaandy". |
| ? | Обозначает, что элемент может как присутствовать, так и отсутствовать. Например, /e?le?/ найдет 'el' в "angel" и 'le' в "angle."Если используется сразу после одного из квантификаторов *, +, ?, или {}, то задает "нежадный" поиск (повторение минимально возможное количество раз, до ближайшего следующего элемента паттерна), в противоположность "жадному" режиму по умолчанию, при котором количество повторений максимально, даже если следующий элемент паттерна тоже подходит. Кроме того, ? используется в предпросмотре, который описан в таблице под (?=), (?!), и (?: ). |
| . | (Десятичная точка) обозначает любой символ, кроме перевода строки: \n \r \u2028 or \u2029. (можно использовать [\s\S] для поиска любого символа, включая переводы строк). Например, /.n/ найдет 'an' и 'on' в "nay, an apple is on the tree", но не 'nay'. |
| (x) | Находит x и запоминает. Это называется "запоминающие скобки". Например, /(foo)/ найдет и запомнит 'foo' в "foo bar." Найденная подстрока хранится в массиве-результате поиска или в предопределенных свойствах объекта RegExp: $1, ..., $9. Кроме того, скобки объединяют то, что в них находится, в единый элемент паттерна. Например, (abc)* - повторение abc 0 и более раз. |
| (?:x) | Находит x, но не запоминает найденное. Это называется "незапоминающие скобки". Найденная подстрока не сохраняется в массиве результатов и свойствах RegExp. Как и все скобки, объединяют находящееся в них в единый подпаттерн. |
x(?=y) | Находит x, только если за x следует y. Например, /Jack(?=Sprat)/ найдет 'Jack', только если за ним следует 'Sprat'. /Jack(?=Sprat|Frost)/ найдет 'Jack', только если за ним следует 'Sprat' или 'Frost'. Однако, ни 'Sprat' ни 'Frost' не войдут в результат поиска. |
x(?!y) | Находит x, только если за x не следует y. Например, /\d+(?!\.)/ найдет число, только если за ним не следует десятичная точка. /\d+(?!\.)/.exec("3.141") найдет 141, но не 3.141. |
x|y | Находит x или y. Например, /green|red/ найдет 'green' в "green apple" и 'red' в "red apple." |
| {n} | Где n - положительное целое число. Находит ровно n повторений предшествующего элемента. Например, /a{2}/ не найдет 'a' в "candy," но найдет оба a в "caandy," и первые два a в "caaandy." |
| {n,} | Где n - положительное целое число. Находит n и более повторений элемента. Например, /a{2,} не найдет 'a' в "candy", но найдет все 'a' в "caandy" и в "caaaaaaandy." |
| {n,m} | Где n и m - положительные целые числа. Находят от n до m повторений элемента. |
| [xyz] | Набор символов. Находит любой из перечисленных символов. Вы можете указать промежуток, используя тире. Например, [abcd] - то же самое, что [a-d]. Найдет 'b' в "brisket" и 'c' в "ache". |
| [^xyz] | Любой символ, кроме указанных в наборе. Вы также можете указать промежуток. Например, [^abc] - то же самое, что [^a-c]. Найдет 'r' в "brisket" и 'h' в "chop." |
| [\b] | Находит символ backspace. (Не путать с \b.) |
| \b | Находит границу слов (латинских), например пробел. (Не путать с [\b]). Например, /\bn\w/ найдет 'no' в "noonday"; /\wy\b/ найдет 'ly' в "possibly yesterday." |
| \B | Обозначает не границу слов. Например, /\w\Bn/ найдет 'on' в "noonday", а /y\B\w/ найдет 'ye' в "possibly yesterday." |
| \cX | Где X - буква от A до Z. Обозначает контрольный символ в строке. Например, /\cM/ обозначает символ Ctrl-M. |
| \d | находит цифру из любого алфавита (у нас же юникод). Используйте [0-9], чтобы найти только обычные цифры. Например, /\d/ или /[0-9]/ найдет '2' в "B2 is the suite number." |
| \D | Найдет нецифровой символ (все алфавиты). [^0-9] - эквивалент для обычных цифр. Например, /\D/ или /[^0-9]/ найдет 'B' в "B2 is the suite number." |
| \f,\r,\n | Соответствующие спецсимволы form-feed, line-feed, перевод строки. |
| \s | Найдет любой пробельный символ, включая пробел, табуляцию, переводы строки и другие юникодные пробельные символы. Например, /\s\w*/ найдет ' bar' в "foo bar." |
| \S | Найдет любой символ, кроме пробельного. Например, /\S\w*/ найдет 'foo' в "foo bar." |
| \t | Символ табуляции. |
| \v | Символ вертикальной табуляции. |
| \w | Найдет любой словесный (латинский алфавит) символ, включая буквы, цифры и знак подчеркивания. Эквивалентно [A-Za-z0-9_]. Например, /\w/ найдет 'a' в "apple," '5' в "$5.28," и '3' в "3D." |
| \W | Найдет любой не-(лат.)словесный символ. Эквивалентно [^A-Za-z0-9_]. Например, /\W/ и /[^$A-Za-z0-9_]/ одинаково найдут '%' в "50%." |
| \n | где n - целое число. Обратная ссылка на n-ю запомненную скобками подстроку. Например, /apple(,)\sorange\1/ найдет 'apple, orange,' в "apple, orange, cherry, peach.". За таблицей есть более полный пример. |
| \0 | Найдет символ NUL. Не добавляйте в конец другие цифры. |
| \xhh | Найдет символ с кодом hh (2 шестнадцатиричных цифры) |
| \uhhhh | Найдет символ с кодом hhhh (4 шестнадцатиричных цифры). |
Пример изменения формата строки
var re = /(\w+)\s(\w+)/; var str = "John Smith"; var newstr = str.replace(re, "$2, $1"); Alert(newstr); // "Smith, John"
Свойства
| global | Тестировать или нет регулярное выражение относительно всех возможных совпадений в строке, или только относительно первого совпадения. |
| ignoreCase | Игнорировать ли регистр при поиске совпадения в строке. |
| lastIndex | Индекс, с которого начинается следующее совпадение. |
| multiline | Искать ли на нескольких строках. |
| source | Текст патэрна |
Методы
| exec | Выполняет поиск совпадения в своём строковом параметре. |
| test | Тестирует на совпадение в своём строковом параметре. |
А также методы объекта String | |
| match | Выполняет поиск совпадения в строке. Возвращает массив информации, или null при отсутствии совпадения. |
| search | Тестирует на наличие совпадений в строке. Возвращает индекс совпадения или -1, если поиск завершился неудачно. |
| replace | Выполняет поиск совпадения в строке и заменяет найденные подстроки замещающей подстрокой. |
| split | Использует регулярное выражение или фиксированную строку для разделения строки на массив подстрок. |
global
Используется ли флаг "g" в регулярном выражении.
Синтаксис
regexp.global
Описание, комментарии, примеры
global это свойство отдельного объекта регулярного выражения.
Вы не можете изменять это свойство явно.
Значение global будет true, если флаг "g" используется; иначе - false. Флаг "g" указывает, что регулярное выражение должно проверяться относительно всех возможных совпадений в строке.
//Определим произвольное регулярное выражение
var regexp = /Шаблон пример/g;
/* В случае если regexp содержит модификатор g выведем
"Модификатор g установлен", в противном случае выведем
"Модификатор g не установлен" */
if (regexp.global)
Alert("Модификатор g установлен");
else
Alert("Модификатор g не установлен");
ignoreCase
Используется ли флаг "i" в регулярном выражении.
Синтаксис
regexp.ignoreCase
Описание, комментарии, примеры
ignoreCase это свойство отдельного объекта регулярного выражения.
Вы не можете изменять это свойство явно.
Значение ignoreCase будет true, если флаг "i" используется; иначе - false. Флаг "i" указывает, что регистр символов должен игнорироваться при поиске совпадений в строке.
//Определим произвольное регулярное выражение
var regexp = /Шаблон пример/i;
/* В случае если regexp содержит модификатор i выведем
"Модификатор i установлен", в противном случае выведем
"Модификатор i не установлен" */
if (regexp.ignoreCase)
Alert("Модификатор i установлен");
else
Alert("Модификатор i не установлен");
lastIndex
Свойство lastIndex указывает позицию, с которой начнется следующий поиск.
Синтаксис
regexp.lastIndex
Комментарии
Это свойство будет работать только если в регулярном выражении установлен модификатор g.
Данное свойство возвращает целое число, которое обозначает позицию последнего символа найденного с помощью метода exec или test.
Пример
//Определим произвольное регулярное выражение
var str = "Я короткая строка";
//Зададим регулярное выражение
var regexp = /о/g;
//Совершим глобальный поиск 'o' в строке текста и будем отображать
//позицию после каждого найденного совпадения
while (regexp.test(str)==true)
{
Alert( regexp.lastIndex );
}
multiline
Используется ли флаг "m" в регулярном выражении.
Синтаксис
regexp.global
Описание, комментарии, примеры
multiline это свойство отдельного объекта регулярного выражения.
Вы не можете изменять это свойство явно.
Значение multiline будет true, если флаг "g" используется; иначе - false. Флаг "g" указывает, что регулярное выражение должно проверяться относительно всех возможных совпадений в строке.
//Определим произвольное регулярное выражение
var regexp = /Шаблон пример/m;
/* В случае если regexp содержит модификатор g выведем
"Модификатор g установлен", в противном случае выведем
"Модификатор g не установлен" */
if (regexp.multiline)
Alert("Модификатор m установлен");
else
Alert("Модификатор g не установлен");
source
Свойство source возвращает содержимое шаблона регулярного выражения
Синтаксис
regexp.source
Комментарии
Свойство "только для чтения", содержащее текст патэрна, исключая слэши (/) и флаги "g" и "i".
Вы не можете изменять это свойство явно.
Пример
//Определим произвольное регулярное выражение var regexp = /Шаблон пример/g; //Возвратим содержимое его шаблона Alert(regexp.source);
exec
Метод exec проверяет строку на наличие совпадений с регулярным выражением.
Синтаксис
regexp.exec(str)
Параметры
- str
- Строка, в которой будет искаться наличие совпадений с регулярным выражением (
regexp).
Возвращаемое значение
Если сопоставление успешно выполнилось, метод exec возвращает массив (array) и обновляет свойства объекта регулярного выражения (regexp):
Массив (array) | |
| array[0] | Сопоставленная подстрока |
| array[1], array[2], ... | Сопоставившиеся подстроки в круглых скобках, если они присутствуют. Количество возможных подстрок ничем не ограничено. |
| array['index'] | Позиция символа, с которого начинается сопоставленная подстрока. |
| array['input'] | Исходная строка |
Объект регулярного выражения (regexp): | |
| reqexp.lastIndex | Индекс начала следующего совпадения. Если отсутствует флаг "g", остаётся равным нулю. |
| reqexp.ignoreCase | Указывает, что в регулярном выражении используется флаг игнорирования регистра "i". |
| reqexp.global | Указывает, что в регулярном выражении используется флаг глобального сопоставления "g". |
| reqexp.multiline | Указывает, что в регулярном выражении используется флаг сопоставления по нескольким строкам "m". |
| reqexp.source | Текст шаблона регулярного выражения. |
Если сопоставление не удалось, метод exec возвращает null.
Описание, комментарии, примеры
Метод exec ведёт себя по-разному, в зависимости от того, есть ли у регэкспа флаг "g":
- Если флага "g" нет, то regexp.exec(str) ищет и возвращает первое совпадение
- Если флаг "g" есть, то вызов regexp.exec возвращает первое совпадение и запоминает его позицию в свойстве
regexp.lastIndex. Последующий поиск он начнёт уже с этой позиции. Если совпадений не найдено, то сбрасываетregexp.lastIndexв ноль.
var regexp = /th(..)/g;
var str = "something this";
while ( (arr=regexp.exec(str)) != null) {
Alert(
"\narr[0] = " + arr[0] +
"\narr[1] = " + arr[1] +
"\narr['index'] = " + arr.index +
"\narr['input'] = " + arr.input +
"\nregexp.lastIndex = " + regexp.lastIndex +
"\nregexp.ignoreCase = " + regexp.ignoreCase +
"\nregexp.global = " + regexp.global +
"\nregexp.multiline = " + regexp.multiline +
"\nregexp.source = " + regexp.source );
}
test
Метод test проверяет строку на наличие совпадений с регулярным выражением.
Синтаксис
regexp.test([str])
Параметры
- str
- Строка, в которой будет искаться наличие совпадений с регулярным выражением (
regexp).
Возвращаемое значение
Метод возвращает true если совпадения были найдены, и false если нет.
Комментарии
Метод используется, чтобы выяснить, есть ли совпадения регулярного выражения со строкой, аналогично String#search.Чтобы получить сами совпадения - используйте exec или String#match.
Пример
//Зададим строку текста var str = "Европа — одна из шести частей света."; //Зададим регулярное выражение с шаблоном "Европа" regexp = /Европа/; //И регулярное выражение с шаблоном "Африка" regexp2 = /Африка/; //Проверим имеются ли совпадения между регулярными выражениями //и строкой и отобразим результат Alert( regexp.test(str)+"\n"+ regexp2.test(str));
Особенности регулярных выражений в Javascript
Регулярные выражения в javascript немного странные. Вроде – обычные, но с подводными камнями, на которые натыкаются даже опытные javascript-разработчики.
Точка и перенос строки
В javascript мультилайн режим (флаг "m") влияет только на символы ^ и $, которые начинают матчиться с началом и концом строки, а не всего текста.
Точка по-прежнему – любой символ, кроме новой строки. В javascript нет флага, который устанавливает мультилайн-режим для точки. Для того, чтобы заматчить совсем что угодно – используйте [\s\S].
function bbtagit(text) {
text = text.replace(/\[u\]([\s\S]*)\[.u\]/gim, '<u>$1</u>');
return text
}
var line = "[u]мой\n текст[/u]"
Alert( bbtagit(line) );
Жадность
Все регулярные выражения в javascript – жадные. То есть, выражение старается отхватить как можно больший кусок строки.
Например, мы хотим заменить все открывающие тэги <a>. На что и почему – не так важно.
var text = '1 <A href="#">...</A> 2' text = text.replace(/<A(.*)>/, 'TEST') Alert(text)
При запуске вы увидите, что заменяется не открывающий тэг, а вся ссылка, выражение матчит ее от начала и до конца.
Это происходит из-за того, что точка-звездочка в «жадном» режиме пытается захватить как можно больше, в нашем случае – это как раз до последнего >.
Для переключение точки-звездочки в нежадный режим надо добавить знак «?» после звездочки.
В нежадном режиме точка-звездочка пустит поиск дальше сразу, как только нашла совпадение:
var text = '1 <A href="#">...</A> 2' text = text.replace(/<A(.*?)>/, 'TEST') Alert(text)
Юникод: флаг "u" и класс \p{...}
В JavaScript для строк используется кодировка Юникод. Обычно символы кодируются с помощью 2 байтов, что позволяет закодировать максимум 65536 символов.
Этого диапазона не хватает для того, чтобы закодировать все символы.
Поэтому некоторые редкие символы кодируются с помощью 4 байтов, например
𝒳 (математический X) или 😄 (смайлик), некоторые иероглифы, и т.п.
В таблице ниже приведены Юникоды нескольких символов:
| Символ | Юникод | Количество байт в Юникоде |
|---|---|---|
| a | 0x0061 | 2 |
| ≈ | 0x2248 | 2 |
| 𝒳 | 0x1d4b3 | 4 |
| 𝒴 | 0x1d4b4 | 4 |
| 😄 | 0x1f604 | 4 |
Таким образом, символы типа a и ≈ занимают по 2 байта, а коды для 𝒳, 𝒴 и 😄 – длиннее, в них 4 байта.
Раньше на момент создания языка JavaScript, кодировка Юникод была проще: символов в 4 байта не существовало. И, хотя это время давно прошло, многие строковые функции всё ещё могут работать некорректно.
Например, свойство length считает, что здесь два символа:
Alert('😍'.length); // 2
Alert('𝒳'.length); // 2
…Но видно, что только один, верно? Дело в том, что свойство length воспринимает 4-байтовый символ как два символа по 2 байта. Это неверно, потому что эти два символа должны восприниматься как единое целое (так называемая «суррогатная пара».
Регулярные выражения также по умолчанию воспринимают 4-байтные «длинные символы» как пары 2-байтных. Как и со строками, это может приводить к странным результатам.
В отличие от строк, у регулярных выражений есть специальный флаг u,
который исправляет эту проблему. При его наличии регулярное выражение
работает с 4-байтными символами правильно. И, кроме того, становится
доступным поиск по Юникодным свойствам.
Юникодные свойства \p{…}
Каждому символу в кодировке Юникод соответствует множество свойств. Они описывают к какой «категории» относится символ, содержат различную информацию о нём.
Например, свойство Letter у символа означает, что это буква какого-то алфавита, причём любого. А свойство Number означает, что это цифра: возможно, арабская или китайская, и т.д.
В регулярном выражении можно искать символ с заданным свойством, указав его в \p{…}. Для таких регулярных выражений обязательно использовать флаг u.
Например, \p{Letter} обозначает букву в любом языке. Также можно использовать запись \p{L}, так как L – это псевдоним Letter. Существуют короткие записи почти для всех свойств.
В примере ниже будут найдены английская, грузинская и корейская буквы:
let str = "A ბ ㄱ";
Alert( str.match(/\p{L}/gu) ); // A,ბ,ㄱ
Alert( str.match(/\p{L}/g) ); // null (ничего не нашло, так как \p не работает без флага "u")
Вот основные категории символов и их подкатегории:
- Буквы
L - в нижнем регистре
Ll,- модификаторы
Lm,- заглавные буквы
Lt,- в верхнем регистре
Lu,- прочие
Lo.- в нижнем регистре
- Числа
N - десятичная цифра
Nd,- цифры обозначаемые буквами (римские)
Nl,- прочие
No.- десятичная цифра
- Знаки пунктуации
P - соединители
Pc,- тире
Pd,- открывающие кавычки
Pi,- закрывающие кавычки
Pf,- открывающие скобки
Ps,- закрывающие скобки
Pe,- прочее
Po.- соединители
- Отметки
M(например, акценты) - двоеточия
Mc,- вложения
Me,- апострофы
Mn.- двоеточия
- Символы
S - валюты
Sc,- модификаторы
Sk,- математические
Sm,- прочие
So.- валюты
- Разделители
Z - линия
Zl,- параграф
Zp,- пробел
Zs.- линия
- Прочие
C - контрольные
Cc,- форматирование
Cf,- не назначенные
Cn,- для приватного использования
Co,- суррогаты
Cs.- контрольные
Так что, например, если нужны буквы в нижнем регистре, то можно написать \p{Ll}, знаки пунктуации: \p{P} и так далее.
Есть и другие категории – производные, например:
Alphabetic(Alpha), включающая в себя буквыL, плюс «буквенные цифры»Nl(например Ⅻ – символ для римской записи числа 12), и некоторые другие символыOther_Alphabetic(OAlpha).Hex_Digitвключает символы для шестнадцатеричных чисел:0-9,a-f.- И так далее.
Юникод поддерживает много различных свойств, их полное перечисление потребовало бы очень много места, поэтому вот ссылки:
- По символу посмотреть его свойства: https://unicode.org/cldr/utility/character.jsp.
- По свойству посмотреть символы с ним: https://unicode.org/cldr/utility/list-unicodeset.jsp.
- Короткие псевдонимы для свойств: https://www.unicode.org/Public/UCD/latest/ucd/PropertyValueAliases.txt.
- Полная база Юникод-символов в текстовом формате вместе со всеми свойствами, находится здесь: https://www.unicode.org/Public/UCD/latest/ucd/.
Пример: шестнадцатеричные числа
Например, поиск шестнадцатеричного числа, записанные в формате xFF, где вместо F может быть любая шестнадцатеричная цифра (0…9 или A…F).
Шестнадцатеричная цифра может быть обозначена как \p{Hex_Digit}:
let regexp = /x\p{Hex_Digit}\p{Hex_Digit}/u;
Alert("число: xAF".match(regexp)); // xAF
Пример: китайские иероглифы
В Юникоде есть свойство Script (система написания), которое может иметь значения Cyrillic (Кириллическая), Greek (Греческая), Arabic (Арабская), Han (Китайская) и так далее, здесь полный список.
Для поиска символов в нужной системе мы должны установить Script=<значение>, например для поиска кириллических букв: \p{sc=Cyrillic}, для китайских иероглифов: \p{sc=Han}, и так далее:
let regexp = /\p{sc=Han}/gu; // вернёт китайские иероглифы
let str = `Hello Привет 你好 123_456`;
Alert( str.match(regexp) ); // 你,好
Пример: валют
Символы, обозначающие валюты, такие как $, €, ¥, имеют свойство \p{Currency_Symbol}, короткая запись: \p{Sc}.
Используеся, чтобы поискать цены в формате «валюта, за которой идёт цифра»:
let regexp = /\p{Sc}\d/gu;
let str = `Цены: $2, €1, ¥9`;
Alert( str.match(regexp) ); // $2,€1,¥9
Таким образом флаг u включает поддержку Юникода в регулярных выражениях.
Конкретно, это означает, что:
- Символы из 4 байт воспринимаются как единое целое, а не как два символа по 2 байта.
- Работает поиск по Юникодным свойствам
\p{…}.
С помощью Юникодных свойств можно искать слова на нужных языках, специальные символы (кавычки, обозначения валюты) и так далее.