- Операторы
- Управляющие инструкции
- 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{…}
.
С помощью Юникодных свойств можно искать слова на нужных языках, специальные символы (кавычки, обозначения валюты) и так далее.