Конструктор объекта regexp превращает регулярное выражение в строку

Обновлено: 02.05.2024

  1. Объект RegExp
  2. Спецсимволы в регулярном выражении
  3. Проверка результатов: метод test
  4. Поиск совпадений: метод exec
  5. Строковые методы, поиск и замена
    1. Метод search(regexp)
    2. Метод match(regexp)
    3. Замена, replace
    4. Спецсимволы в строке замены
    5. Замена через функцию

    Регулярные выражения в javascript имеют особую краткую форму и стандартный PCRE-синтаксис.

    Работают они через специальный объект RegExp.

    Кроме того, у строк есть свои методы search,match,replace, но чтобы их понять - разберем-таки сначала RegExp .

    Объект RegExp

    Объект типа RegExp , или, короче, регулярное выражение, можно создать двумя путями

    pattern - регулярное выражение для поиска (о замене - позже), а флаги - строка из любой комбинации символов g (глобальный поиск), i (регистр неважен) и m (многострочный поиск).

    Первый способ используется часто, второй - иногда. Например, два таких вызова эквивалентны:

    При втором вызове - т.к регулярное выражение в кавычках, то нужно дублировать \

    При поиске можно использовать большинство возможностей современного PCRE-синтаксиса.

    Спецсимволы в регулярном выражении

    Символ Значение
    \ Для обычных символов - делает их специальными. Например, выражение /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 или более раз. Эквивалентно . Например, /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 повторений предшествующего элемента. Например, /a/ не найдет 'a' в "candy," но найдет оба a в "caandy," и первые два a в "caaandy."
    Где n - положительное целое число. Находит n и более повторений элемента. Например, /a не найдет 'a' в "candy", но найдет все 'a' в "caandy" и в "caaaaaaandy."
    Где n и m - положительные целые числа. Находят от n до m повторений элемента.
    [ xyz ] Набор символов. Находит любой из перечисленных символов. Вы можете указать промежуток, используя тире. Например, [abcd] - то же самое, что [a-d] . Найдет 'b' в "brisket", а также 'a' и '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."
    \c X Где X - буква от A до Z. Обозначает контрольный символ в строке. Например, /\cM/ обозначает символ Ctrl-M.
    \d находит цифру из любого алфавита (у нас же юникод). Испльзуйте 8, чтобы найти только обычные цифры. Например, /\d/ или /1/ найдет '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. Не добавляйте в конец другие цифры.
    \x hh Найдет символ с кодом hh (2 шестнадцатиричных цифры)
    \u hhhh Найдет символ с кодом hhhh (4 шестнадцатиричных цифры).

    Проверка результатов: метод test

    Чтобы просто проверить, подходит ли строка под регулярное выражение, используется метод test :

    Метод test начинает поиск, начиная со свойства lastIndex объекта RegExp , если оно установлено.

    Поиск совпадений: метод exec

    Метод exec возвращает массив и ставит свойства регулярного выражения.
    Если совпадений нет, то возвращается null.

    В результате выполнения скрипта будут такие результаты:

    Объект Свойство/Индекс Описания Пример
    myArray Содержимое myArray . ["dbBd", "bB", "d"]
    index Индекс совпадения (от 0) 1
    input Исходная строка. cdbBdbsbz
    [0] Последние совпавшие символы dbBd
    [1], . [ n ] Совпадения во вложенных скобках, если есть. Число вложенных скобок не ограничено. [1] = bB
    [2] = d
    myRe lastIndex Индекс, с которого начинать следующий поиск. 5
    ignoreCase Показывает, что был включен регистронезависимый поиск, флаг " i ". true
    global Показывает, что был включен флаг " g " поиска всех совпадений. true
    multiline Показывает, был ли включен флаг многострочного поиска " m ". false
    source Текст паттерна. d(b+)(d)

    Если в регулярном выражении включен флаг " g ", Вы можете вызывать метод exec много раз для поиска последовательных совпадений в той же строке. Когда Вы это делаете, поиск начинается на подстроке str , с индекса lastIndex . Например, вот такой скрипт:

    Этот скрипт выведет следующий текст:

    В следующем примере функция выполняет поиск по input. Затем делается цикл по массиву, чтобы посмотреть, есть ли другие имена.

    Строковые методы, поиск и замена

    Следующие методы работают с регулярными выражениями из строк.

    Все методы, кроме replace, можно вызывать как с объектами типа regexp в аргументах, так и со строками, которые автоматом преобразуются в объекты RegExp.

    Так что вызовы эквивалентны:

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

    Метод search(regexp)

    Возвращает индекс регулярного выражения в строке, или -1.

    Если Вы хотите знать, подходит ли строка под регулярное выражение, используйте метод search (аналогично RegExp-методы test ). Чтобы получить больше информации, используйте более медленный метод match (аналогичный методу RegExp exec ).

    Метод match(regexp)

    Если в regexp нет флага g , то возвращает тот же результат, что regexp.exec(string) .

    Если в regexp есть флаг g , то возвращает массив со всеми совпадениями.

    Чтобы просто узнать, подходит ли строка под регулярное выражение regexp , используйте regexp.test(string) .

    Если Вы хотите получить первый результат - попробуйте r egexp.exec(string) .

    В следующем примере match используется, чтобы найти "Chapter", за которой следует 1 или более цифр, а затем цифры, разделенные точкой. В регулярном выражении есть флаг i , так что регистр будет игнорироваться.

    Скрипт выдаст массив из совпадений:

    • Chapter 3.4.5.1 - полностью совпавшая строка
    • 3.4.5.1 - первая скобка
    • .1 - внутренняя скобка

    Следующий пример демонстрирует использование флагов глобального и регистронезависимого поиска с match . Будут найдены все буквы от А до Е и от а до е, каждая - в отдельном элементе массива.

    Замена, replace

    Метод replace может заменять вхождения регулярного выражения не только на строку, но и на результат выполнения функции. Его полный синтаксис - такой:

    regexp Объект RegExp. Его вхождения будут заменены на значение, которое вернет параметр номер 2 substr Строка, которая будет заменена на newSubStr . newSubStr Строка, которая заменяет подстроку из аргумента номер 1. function Функция, которая может быть вызвана для генерации новой подстроки (чтобы подставить ее вместо подстроки, полученной из аргумента 1).

    Метод replace не меняет строку, на которой вызван, а просто возвращает новую, измененную строку.

    Чтобы осуществить глобальную замену, включите в регулярное выражение флаг "g" .

    Если первый аргумент - строка, то она не преобразуется в регулярное выражение, так что, например,

    Вызов replace оставил строку без изменения, т.к искал не регулярное выражение \s , а строку "\s".

    Спецсимволы в строке замены

    В строке замены могут быть такие спецсимволы:

    Pattern Inserts
    $$ Вставляет "$".
    $& Вставляет найденную подстроку.
    $` Вставляет часть строки, которая предшествует найденному вхождению.
    $' Вставляет часть строки, которая идет после найденного вхождения.
    $ n or $ nn Где n или nn - десятичные цифры, вставляет подстроку вхождения, запомненную n -й вложенной скобкой, если первый аргумент - объект RegExp.

    Замена через функцию

    Если Вы указываете вторым параметром функцию, то она выполняется при каждом совпадении.

    В функции можно динамически генерировать и возвращать строку подстановки.

    Первый параметр функции - найденная подстрока. Если первым аргументом replace является объект RegExp , то следующие n параметров содержат совпадения из вложенных скобок. Последние два параметра - позиция в строке, на которой произошло совпадение и сама строка.

    Например, следующий вызов replace возвратит XXzzzz - XX , zzzz.

    Как видите, тут две скобки в регулярном выражении, и потому в функции два параметра p1 , p2 .
    Если бы были три скобки, то в функцию пришлось бы добавить параметр p3 .

    Следующая функция заменяет слова типа borderTop на border-top :

    Статичные регэкспы

    В некоторых реализациях javascript регэкспы, заданные коротким синтаксисом /. / - статичны. То есть, такой объект создается один раз в некоторых реализациях JS, например в Firefox. В Chrome все ок.

    По стандарту эта возможность разрешена ES3, но запрещена ES5.

    Из-за того, что lastIndex при глобальном поиске меняется, а сам объект регэкспа статичен, первый поиск увеличивает lastIndex , а последующие - продолжают искать со старого lastIndex , т.е. могут возвращать не все результаты.

    При поиске всех совпадений в цикле проблем не возникает, т.к. последняя итерация (неудачная) обнуляет lastIndex .

    Дополнительно

    Для общего понимания регулярных выражений можно почитать Статью в wikipedia.

    Более подробно они описаны в книге (англ.) Beginning Regular Expressions.

    Конструктор RegExp создаёт объект регулярного выражения для сопоставления текста с шаблоном.

    Введение в то, что представляют собой регулярные выражения, читайте в главе «Регулярные выражения» в руководстве по JavaScript.

    Интерактивный пример

    Синтаксис

    Возможны как литеральная запись, так и запись через конструктор:

    Параметры

    Если определён, может принимать любую комбинацию нижеследующих значений:

    g глобальное сопоставление i игнорирование регистра при сопоставлении m сопоставление по нескольким строкам; символы начала и конца (^ и $) начинают работать по нескольким строкам (то есть, происходит сопоставление с началом или концом каждой строки (строки разделяются символами \n или \r), а не только с началом или концом всей вводимой строки) y Experimental «липкий» поиск; сопоставление в целевой строке начинается с индекса, на который указывает свойство lastIndex этого регулярного выражения (и не пытается сопоставиться с любого более позднего индекса).

    Описание

    Существует два способа создания объекта RegExp : литеральная запись и использование конструктора. При записи строк параметры в литеральной записи не используют символы кавычек, в то время как параметры функции-конструктора используют кавычки. Так что следующие выражения создают одинаковые регулярные выражения:

    Литеральная запись обеспечивает компиляцию регулярного выражения при вычислении выражения. Используйте литеральную запись если регулярное выражение будет неизменным. Например, если вы используете литеральную запись для конструирования регулярного выражения, используемого в цикле, регулярное выражение не будет перекомпилироваться на каждой итерации.

    Конструктор объекта регулярного выражения, например, new RegExp('ab+c') , обеспечивает компиляцию регулярного выражения во время выполнения. Используйте функцию-конструктор, если вы знаете, что шаблон регулярного выражения будет меняться или если вы не знаете шаблон и получаете его из внешних источников, например, из пользовательского ввода.

    При использовании функции-конструктора необходимо использовать обычные правила экранирования в строках (предварять специальные символы символом обратного слеша «\»). Например, следующие выражения эквивалентны:

    Значение специальных символов в регулярных выражениях

    (Точка, десятичная запятая) сопоставляется с любым символом за исключением символов новой строки: \n , \r , \u2028 или \u2029 .

    Обратите внимание, что флаг многострочности m не изменяет поведение точки. Так что для сопоставления с шаблона с несколькими строками используйте набор символов [^] (конечно, если только вам не нужно поддерживать старые версии IE), он сопоставляется с любым символом, включая символы новой строки.

    Например, шаблон /.н/ сопоставляется с подстрокой «ан», но не подстрокой «ну», во фразе «ну что, потанцуем».

    Сопоставляется с символом цифры в базовом латинском алфавите. Эквивалентен набору символов 8 .

    Например, шаблоны /\d/ и /9/ сопоставляются с подстрокой «2» в строке «B2 — это номер люкс».

    Сопоставляется с любым символом, который не является цифрой в базовом латинском алфавите. Эквивалентен набору символов [^0-9] .

    Например, шаблоны /\D/ и /[^0-9]/ сопоставляются с подстрокой «B» в строке «B2 — это номер люкс».

    Сопоставляется с любым алфавитно-цифровым символом из базового латинского алфавита, включая символ подчёркивания. Эквивалентен набору символов [A-Za-z0-9_] .

    Например, шаблон /\w/ сопоставляется с подстрокой «a» в строке «apple», с подстрокой «5» в строке «$5.28» и с подстрокой «3» в строке «3D».

    Сопоставляется с любым символом из базового латинского алфавита, не являющимся символом, из которых состоят слова. Эквивалентен набору символов [^A-Za-z0-9_] .

    Например, шаблоны /\W/ и /[^A-Za-z0-9_]/ сопоставляются с подстрокой «%» в строке «50%».

    Сопоставляется с одиночным пробельным символом, который включает в себя пробел, табуляцию, подачу страницы, перевод строки и другие пробельные символы Юникода. Эквивалентен набору символов [ \f\n\r\t\v​\u00a0\u1680​\u180e\u2000​\u2001\u2002​\u2003\u2004​\u2005\u2006​\u2007\u2008​\u2009\u200a​\u2028\u2029​​\u202f\u205f​\u3000] .

    Например, шаблон /\s\w*/ сопоставляется с подстрокой « bar» в строке «foo bar».

    Сопоставляется с одиночным символом, не являющимся пробельным. Эквивалентен набору символов [^ \f\n\r\t\v​\u00a0\u1680​\u180e\u2000​\u2001\u2002​\u2003\u2004​\u2005\u2006​\u2007\u2008​\u2009\u200a​\u2028\u2029​\u202f\u205f​\u3000] .

    Например, шаблон /\S\w*/ сопоставляется с подстрокой «foo» в строке «foo bar».

    Где X является буквой от «A» до «Z». Сопоставляется с управляющим символом в строке.

    Например, шаблон /\cM/ сопоставляется с символом control-M в строке.

    Для символов, которые обычно трактуются буквально, указывает, что следующий символ является специальным и не должен интерпретироваться буквально.

    Например, шаблон /b/ сопоставляется с символом «b». Поместив перед ним символ обратного слеша, то есть превратив шаблон в /\b/ , символ приобретёт специальное значение, обозначающее сопоставление с границей слова.

    Для символов, которые обычно трактуются специальным образом, указывает, что следующий символ не является специальным и должен интерпретироваться буквально.

    Например, звёздочка «*» является специальным символом, обозначающим ноль или более вхождений предшествующего символа при сопоставлении; поэтому шаблон /a*/ означает сопоставление с нулём или более символов «a». Для буквального сопоставления со звёздочкой * предварите её символом обратного слеша; например, шаблон /a\*/ сопоставляется со строкой «a*».

    Набор символов. Сопоставляется с любым из заключённых в квадратные скобки символов. С помощью дефиса вы можете определить диапазон символов.

    Например, шаблон [абвгд] означает тоже самое, что и шаблон [а-д] . Они сопоставляются с символом «г» в слове «грудинка» и символом «б» в слове «отбивная».

    Отрицательный или дополнительный набор символов. То есть он сопоставляется со всеми символами, что не заключены в квадратные скобки. С помощью дефиса вы можете определить диапазон символов.

    Например, шаблон [^абвгд] означает тоже самое, что и шаблон [^а-д] . Они сопоставляются с символом «е» в слове «бекон» и символом «о» в слове «отбивная».

    Сопоставляется c началом ввода. Если установлен флаг многострочности, также сопоставляется с позицией сразу за символом переноса строки.

    Например, шаблон /^Б/ не сопоставляется с буквой «Б» в строке «буква Б», но сопоставляется с первой буквой «Б» в строке «Буква Б».

    Сопоставляется c концом ввода. Если установлен флаг многострочности, также сопоставляется с позицией сразу перед символом переноса строки.

    Например, шаблон /т$/ не сопоставляется с буквой «т» в слове «кормить», но сопоставляется с ней в слове «кормит».

    Сопоставляется с границей слова нулевой ширины, например с позицией между буквой и пробелом (не путайте его с набором символов [\b] ).

    Например, шаблон /\bпол/ сопоставляется с подстрокой «пол» в строке «в полдень»; шаблон /но\b/ сопоставляется с подстрокой «но» в строке «возможно завтра».

    Сопоставляется с границей не-слов нулевой ширины, например с позицией между двумя буквами или двумя пробелами.

    Например, шаблон /\Bдень/ сопоставляется с подстрокой «день» в строке «в полдень»; шаблон /за\B/ сопоставляется с подстрокой «за» в строке «возможно завтра».

    Сопоставляется с x и запоминает сопоставление. Называется «захватывающие скобки».

    Например, шаблон /(foo)/ сопоставляется с подстрокой «foo» и запоминает её в строке «foo bar». Сопоставленную подстроку можно достать из элементов [1], . [n] результирующего массива или из предопределённых свойств $1, . $9 объекта RegExp .

    Захват групп ведёт к проседанию производительности. Если вам не нужно повторно ссылаться на захваченную подстроку, лучше использовать скобки без захвата (смотрите ниже).

    Где n является целым положительным числом. Обратная ссылка на последнюю сопоставившуюся подстроку в n-ных по счёту круглых скобках в регулярном выражении (нумерация скобок идёт слева направо).

    Например, шаблон /яблоко(,)\sапельсин\1/ сопоставится подстроке «яблоко, апельсин,» в строке «яблоко, апельсин, вишня, персик». Более подробный пример смотрите после этой таблицы.

    Сопоставляется с предшествующим элементом x ноль или более раз.

    Например, шаблон /ела*/ сопоставляется с подстрокой «ел» в строке «Призрак просвистел» и подстрокой «ела» в строке «Птица пропела», но ни с чем не сопоставится в строке «Козёл хмыкнул».

    Сопоставляется с предшествующим элементом x один или более раз. Эквивалентен квантификатору .

    Например, шаблон /о+/ сопоставляется с символом «о» в строке «конфета» и со всеми символами «о» в строке «коооооонфета».

    Сопоставляется с предшествующим элементом x подобно квантификаторам * и + , описанным выше, однако ищет минимально возможное сопоставление.

    Например, шаблон /".*?"/ сопоставляется с подстрокой «"foo"» в строке «"foo" "bar"» и не сопоставляется со строкой «"foo" "bar"», поскольку за звёздочкой * следует символ вопроса ? .

    Сопоставляется с предшествующим элементом x ноль или один раз.

    Например, шаблон /о?то?/ сопоставляется с подстрокой «от» в строке «кот» и подстрокой «то» в строке «ток».

    Если символ используется сразу после какого-то из квантификаторов * , + , ? , или <> , то он делает этот квантификатор «нежадным» (сопоставление происходит минимально возможное количество раз), в противоположность «жадному» поведению квантификатора по умолчанию (сопоставление происходит максимально возможное количество раз).

    Также символ используется в квантификаторах предпросмотра (?=) , (?!) и (?:) , также описанных в этой таблице.

    Сопоставляется с x , только если за x не следует y . Например, шаблон /\d+(?!\.)/ сопоставляется с числом только если за ним не следует десятичная запятая.

    Выражение /\d+(?!\.)/.exec('3.141') сопоставится с «141» но не с «3.141».

    Сопоставляется с x , только если x предшествует y

    Сопоставляется с x , только если x не предшествует y

    Сопоставляется либо с x , либо с y .

    Например, шаблон /зелёное|красное/ сопоставится с подстрокой «зелёное» в строке «зелёное яблоко» и подстрокой «красное» в строке «красное яблоко».

    Где n является целым положительным числом. Сопоставляется точно с n вхождениями предшествующего элемента x.

    Например, шаблон /о/ не сопоставится с символом «о» в слове «конфета», но сопоставится со всеми символами «о» в слове «коонфета» и с первыми двумя символами «о» в слове «кооонфета».

    Где n является целым положительным числом. Сопоставляется по крайней мере с n вхождениями предшествующего элемента x.

    Например, шаблон /о/ не сопоставится с символом «о» в слове «конфета», но сопоставится со всеми символами «о» в словах «коонфета» и даже в «кооооооонфета».

    Где n и m являются целыми положительными числами. Сопоставляется по крайней мере с n но не более, чем с m вхождениями предшествующего элемента x.

    Например, шаблон /о/ ни с чем не сопоставится в слове «кнфета», с символом «о» в слове «конфета», с двумя символами «о» в слове «коонфета» и с первыми тремя символами «о» в слове «кооооооонфета». Обратите внимание, что при сопоставлении со словом «кооооооонфета» сопоставимость только подстрока «ооо», хотя слово содержало гораздо больше символов «о».

    Свойства

    RegExp.prototype (en-US) Позволяет добавлять свойства ко всем объектам регулярных выражений. RegExp.length Значение RegExp.length равно 2.

    Методы

    Глобальный объект RegExp не имеет собственных методов, однако, он наследует некоторые методы через цепочку прототипов.

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



    Мощная картинка для привлечения внимания :) Осторожно, может засосать!

    Но, на самом деле, регулярные выражения — это мощный инструмент, который может помочь вам сэкономить уйму времени. В этом материале мы рассмотрим основы регулярных выражений в JavaScript.

    Создание регулярных выражений в JS

    В JavaScript регулярное выражение — это один из типов объектов, который используется для поиска комбинаций символов в строках.

    Существует два способа создания регулярных выражений.

    Первый заключается в использовании литералов регулярных выражений. При таком подходе шаблон регулярного выражения заключают в слэши. Выглядит это так:


    Второй задействует конструктор объекта RegExp , которому передают строку, из которой он создаёт регулярное выражение:


    В обоих вышеприведённых примерах создаётся один и тот же шаблон — символ c , за которым следует символ a , за которым идёт символ t .

    Какой способ создания регулярных выражений выбрать? Тут стоит придерживаться такого правила: если вы предполагаете пользоваться регулярным выражением так, что оно остаётся неизменным — лучше использовать литерал. Если ваше регулярное выражение является динамическим, оно может меняться в ходе выполнения программы, лучше использовать конструктор RegExp .

    Методы регулярных выражений

    Выше вы могли заметить, что регулярные выражения в JS — это объекты. У объектов, как известно, есть методы, и регулярные выражения — не исключение.

    Один из основных методов регулярных выражения — это .test() , который возвращает логическое значение:


    А именно, этот метод возвращает true если строка содержит совпадение с заданным шаблоном регулярного выражения. Если совпадений не найдено — он возвращает false .

    Рассмотрим следующий пример. У нас имеется две строки и одно регулярное выражение. Мы можем использовать регулярное выражение для проверки того, встречается ли заданный текстовый шаблон в строках:


    Как и ожидается, когда мы проверяем первую строку, str1 , на наличие в ней последовательности символов cat , мы получаем true . А вот проверив вторую строку, str2 , мы в ней cat не находим, поэтому метод .test() возвращает false .

    Базовые конструкции регулярных выражений

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

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

    ▍Символы

    • . (точка) — соответствует любому одиночному символу за исключением переноса строки.
    • * — соответствует предыдущему выражению, которое повторено 0 или более раз.
    • + — соответствует предыдущему выражению, которое повторено 1 или более раз.
    • ? — соответствует предыдущему выражению, повторённому 0 или 1 раз.
    • ^ — соответствует началу строки.
    • $ — соответствует концу строки.

    ▍Группы символов

    • \d — соответствует любому одиночному цифровому символу.
    • \w — соответствует любому символу — цифре, букве, или знаку подчёркивания.
    • [XYZ] — набор символов. Соответствует любому одиночному символу из набора, заданного в скобках. Кроме того, похожим образом можно задавать и диапазоны символов, например — [A-Z] .
    • [XYZ]+ — соответствует символу из скобок, повторённому один или более раз.
    • [^A-Z] — внутри выражений, задающих диапазоны символов, символ ^ используется как знак отрицания. В данном примере шаблону соответствует всё, что не является буквами в верхнем регистре.

    ▍Флаги

    Существует пять необязательных флагов регулярных выражений. Они могут использоваться совместно или раздельно, их помещают после закрывающего слэша. Регулярные выражения с флагами выглядят так: /[A-Z]/g . Мы рассмотрим тут лишь два флага:

    • g — глобальный поиск по строке.
    • i — поиск, нечувствительный к регистру.

    ▍Дополнительные конструкции

    • (x) — захватывающие скобки. Это выражение соответствует x и запоминает это соответствие, в результате, мы можем воспользоваться им позже.
    • (?:x) — незахватывающие скобки. Выражение соответствует x , но не запоминает это соответствие
    • x(?=y) — упреждающее соответствие. Соответствует x только если за ним следует y .

    Более сложные примеры регулярных выражений

    Прежде чем мы приступим к учебному проекту, остановимся подробнее на практическом использовании того, что мы только что рассмотрели.

    Для начала проверим строку на наличие в ней любых цифр. Для того, чтобы это сделать, мы можем использовать шаблон \d . Взгляните на нижеприведённый код. Он возвращает true в тех случаях, когда в исследуемой строке имеется хотя бы одна цифра.


    Как видите, код возвращает true — это неудивительно, так как в исследуемой строке есть четыре цифровых символа.

    А что если нам нужно проверить строку на наличие в ней некоей последовательности цифровых символов? В подобном случае можно воспользоваться шаблоном \d , повторённым несколько раз. Например, для того, чтобы регулярное выражение соответствовало строке 11 , можно воспользоваться конструкцией \d\d , которая описывает два любых последовательно расположенных цифровых символа. Взгляните на этот код:


    Как видно, тут мы проверяем строку на то, имеются ли в ней последовательности одиночных цифр, разделённых чёрточками. Первая строка такому шаблону соответствует, а вторая — нет.

    Как быть, если неважно сколько именно цифр находится до или после чёрточек, если их количество больше или равняется единице? В подобной ситуации можно воспользоваться знаком + для того, чтобы указать, что шаблон /d может встречаться один или более раз. Вот как это выглядит:


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


    Получилось. Теперь давайте рассмотрим это выражение подробнее. На самом деле, тут происходит много интересного.

    Итак, вот регулярное выражение.

    • m — соответствует одиночной букве m .
    • e+ — соответствует букве e , повторённой один или более раз.
    • (ow)+ соответствует сочетанию ow , повторённому один или более раз.
    • w — соответствует одиночной букве w .


    Как видите, если операторы вроде + используются сразу после выражений, заключённых в скобки, они относятся ко всему тому, что находится в скобках.

    Вот ещё один пример, он касается использования оператора ? . Знак вопроса указывает на то, что присутствие предшествующего ему символа в строке необязательно.

    Взгляните на это:


    Как видите, каждое из выражений возвращает true . Это происходит потому что мы сделали символы s в конце последовательностей cat и say необязательными. Кроме того, можно заметить, что в конце регулярного выражения находится флаг i . Благодаря ему при анализе строк игнорируется регистр символов. Именно поэтому регулярное выражение реагирует и на строку cat , и на строку Cat .

    Об экранировании служебных символов

    Регулярные выражения заключают в слэши. Кроме того, некоторые символы, вроде + , ? , и другие, имеют особый смысл. Если вам нужно организовать поиск в строках этих особых символов, их нужно экранировать с помощью обратного слэша. Вот как это выглядит:


    Кроме того, важно отметить, что для поиска одних и тех же строковых конструкций можно использовать различные регулярные выражения. Вот пара примеров:

    • \d — это то же самое, что и 1 . Каждое из этих выражений соответствует любому цифровому символу.
    • \w — это то же самое, что [A-Za-z0-9_] . И то и другое найдёт в строке любой одиночный алфавитно-цифровой символ или знак подчёркивания.

    Проект №1: добавление пробелов в строки, построенные в верблюжьемСтиле

    Теперь пришло время применить полученные знания на практике. В нашем первом проекте мы собираемся написать функцию, которая принимает на вход строку, вроде CamelCase , и добавляет между отдельными словами, из которой она состоит, пробелы. Использование готовой функции, которую мы назовём removeCc , выглядит так:


    Для начал надо написать каркас функции, которая принимает строку и возвращает новую строку:


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


    Это регулярное выражение отреагирует на букву C в строке camelCase . А как добавить пробел перед этой буквой C ?

    Для того, чтобы это сделать, нам понадобятся захватывающие скобки. В регулярных выражениях захватывающие скобки используются для поиска соответствий и для их запоминания. Это позволяет нам воспользоваться сохранёнными значениями тогда, когда они нам понадобятся. Вот как работать с захватывающими скобками:


    Тут вы можете видеть, что мы используем конструкцию $1 для обращения к захваченному значению. Стоит отметить, что если в выражении имеется два набора захватывающих скобок, можно пользоваться выражениями $1 и $2 для того, чтобы ссылаться на захваченные значения в порядке их следования слева направо. При этом захватывающие скобки можно использовать столько раз, сколько нужно в конкретной ситуации.

    Обратите внимание на то, что нам не нужно захватывать значение в скобках. Можно и не использовать его, или использовать незахватывающие скобки с помощью конструкции вида (?:x) . В данном примере находится соответствие с x , но оно не запоминается.

    Вернёмся к нашему проекту. Есть метод объекта String , который можно использовать для работы с захватывающими скобками — это .replace() . Для того, чтобы им воспользоваться, мы будем искать в строке любые заглавные буквы. Вторым аргументом метода, представляющим заменяющее значение, будет сохранённое значение:


    Мы уже близки к решению, хотя цели пока ещё не достигли. Взглянем снова на наш код. Тут мы захватываем заглавные буквы, затем меняем их на эти же буквы. А нам надо, чтобы перед ними оказались пробелы. Сделать это довольно просто — достаточно добавить пробел перед переменной $1 . В результате перед каждой заглавной буквой в строке, которую возвратит функция, будет пробел. В итоге у нас получилось следующее:

    Проект №2: удаление заглавных букв из строки

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

    Сейчас мы займёмся удалением лишних заглавных букв из строки и заменой их на прописные. Прежде чем читать дальше, поразмышляйте над этой проблемой и попытайтесь найти решение. Однако, если у вас ничего не получается — не расстраивайтесь, так как решение нашей задачи, хотя и несложное, нельзя назвать совсем уж простым.

    Итак, первое что нам надо — выбрать все заглавный буквы в строке. Тут используется та же конструкция, что и в предыдущем примере:


    Тут же мы будем использовать и уже знакомый вам метод .replace() , но в этот раз нам, при вызове этого метода, понадобится кое-что новое. Вот как будет выглядеть схема того, что нам нужно. Знаки вопроса указывают на этот новый, пока неизвестный, код:


    Метод .replace() замечателен тем, что мы можем, в качестве его второго параметра, использовать функцию. Эта функция будет вызвана после обнаружения совпадения, а то, что эта функция возвратит, будет использовано в качестве строки, заменяющей то, что нашло регулярное выражение.

    Если мы ещё и используем флаг глобального поиска, функция будет вызываться для каждого совпадения с шаблоном, найденного в строке. Помня об этом, мы можем воспользоваться методом .toLowerCase() объекта String для преобразования входной строки к нужному нам виду. Вот как, с учётом вышесказанного, выглядит решение нашей задачи:

    Проект №3: преобразование к верхнему регистру первую букву первого слова строки

    Это будет наш последний учебный проект, в котором мы собираемся сделать первую букву обрабатываемой строки заглавной. Вот чего мы ждём от новой функции:


    Тут, как и прежде, будем пользоваться методом .replace() . Однако, в этот раз нам нужно найти лишь самый первый символ строки. Для того, чтобы это сделать, задействуем символ ^ . Вспомним один из вышеприведённых примеров:


    Если добавить в начало шаблона символ ^ , true эта конструкция уже не возвратит. Произойдёт это из-за того, что слово cat находится не в начале строки:


    Нам надо, чтобы специальный символ ^ воздействовал на любой символ в нижнем регистре, находящийся в начале строки. Поэтому мы добавляем его прямо перед конструкцией [a-z] . В результате регулярное выражение отреагирует только на первую букву строки в нижнем регистре:


    Кроме того, тут мы не используем флаг глобального поиска, так как нам нужно найти лишь одно совпадение с шаблоном. Теперь всё, что осталось сделать — это преобразовать найденный символ к верхнему регистру. Сделать это можно с помощью строкового метода .toUpperCase() :

    Совместное использование ранее созданных функций

    Теперь у нас есть всё необходимое для того, чтобы превращать строки, записанные в верблюжьемСтиле, в строки, отдельные слова в которых разделены пробелами, и которые начинаются с заглавной буквы, при том, что слова, находящиеся внутри этих строк, будут записаны прописными буквами. Вот как будет выглядеть совместное использование только что созданных функций:

    Итоги

    Как видите, хотя регулярные выражения и выглядят для неподготовленного человека весьма непривычно, их вполне можно освоить. Лучший способ изучения регулярных выражений — практика. Предлагаем вам попробовать следующее: напишите, на основе трёх созданных нами функций, одну, которая преобразует переданную ей строку, вроде camelCase, в обычное предложение и добавляет после его последнего слова точку.

    Регулярные выражения – мощное средство поиска и замены в строке.

    В JavaScript регулярные выражения реализованы отдельным объектом RegExp и интегрированы в методы строк.

    Регулярные выражения

    Регулярное выражение (оно же «регэксп», «регулярка» или просто «рег»), состоит из шаблона (также говорят «паттерн») и необязательных флагов.

    Существует два синтаксиса для создания регулярного выражения.

    …И короткий синтаксис, использующий слеши "/" :

    Слеши /. / говорят JavaScript о том, что это регулярное выражение. Они играют здесь ту же роль, что и кавычки для обозначения строк.

    Регулярное выражение regexp в обоих случаях является объектом встроенного класса RegExp .

    Основная разница между этими двумя способами создания заключается в том, что слеши /. / не допускают никаких вставок переменных (наподобие возможных в строках через $ <. >). Они полностью статичны.

    Слеши используются, когда мы на момент написания кода точно знаем, каким будет регулярное выражение – и это большинство ситуаций. А new RegExp – когда мы хотим создать регулярное выражение «на лету» из динамически сгенерированной строки, например:

    Флаги

    Регулярные выражения могут иметь флаги, которые влияют на поиск.

    В JavaScript их всего шесть:

    i С этим флагом поиск не зависит от регистра: нет разницы между A и a (см. пример ниже). g С этим флагом поиск ищет все совпадения, без него – только первое. m Многострочный режим (рассматривается в главе Многострочный режим якорей ^ $, флаг "m"). s Включает режим «dotall», при котором точка . может соответствовать символу перевода строки \n (рассматривается в главе Символьные классы). u Включает полную поддержку Юникода. Флаг разрешает корректную обработку суррогатных пар (подробнее об этом в главе Юникод: флаг "u" и класс \p ). y Режим поиска на конкретной позиции в тексте (описан в главе Поиск на заданной позиции, флаг "y")

    Здесь и далее в тексте используется следующая цветовая схема:

    • регулярное выражение – красный
    • строка (там где происходит поиск) – синий
    • результат – зелёный

    Поиск: str.match

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

    Метод str.match(regexp) для строки str возвращает совпадения с регулярным выражением regexp .

    У него есть три режима работы:

    Если у регулярного выражения есть флаг g , то он возвращает массив всех совпадений:

    Обратите внимание: найдены и Любо и любо , благодаря флагу i , который делает регулярное выражение регистронезависимым.

    Если такого флага нет, то возвращает только первое совпадение в виде массива, в котором по индексу 0 находится совпадение, и есть свойства с дополнительной информацией о нём:

    В этом массиве могут быть и другие индексы, кроме 0 , если часть регулярного выражения выделена в скобки. Мы разберём это в главе Скобочные группы.

    И, наконец, если совпадений нет, то, вне зависимости от наличия флага g , возвращается null .

    Это очень важный нюанс. При отсутствии совпадений возвращается не пустой массив, а именно null . Если об этом забыть, можно легко допустить ошибку, например:


    Регулярные выражения представляют шаблон, который используется для поиска или модификации строки. Для работы с регулярными выражениями в JavaScript определен объект RegExp .

    Определить регулярное выражение можно двумя способами:

    Используемое здесь регулярное выражение довольно простое: оно состоит из одного слова "hello". В первом случае выражение помещается между двумя косыми чертами, а во втором случае используется конструктор RegExp, в который выражение передается в виде строки.

    Методы RegExp

    Чтобы определить, соответствует ли регулярное выражение строке, в объекте RegExp определен метод test() . Этот метод возвращает true , если строка соответствует регулярному выражению, и false , если не соответствует.

    Аналогично работает метод exec - он также проверяет, соответствует ли строка регулярному выражению, только теперь данный метод возвращает ту часть строки, которая соответствует выражению. Если соответствий нет, то возвращается значение null .

    Группы символов

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

    Выражение [абв] указывает на то, что строка должна иметь одну из трех букв.

    Если нам надо определить наличие в строке буквенных символов из определенного диапазона, то можно сразу задать этот диапазон:

    В данном случае строка должна содержать хотя бы один символ из диапазона а-я.

    Если, наоборот, не надо, чтобы строка имела только определенные символы, то необходимо в квадратных скобках перед перечислением символов ставить знак ^:

    В первом случае строка не должна иметь только символы из диапазона а-я, но поскольку строка "обороноспособность" состоит только из символов из этого диапазона, то метод test() возвращает false, то есть регулярное выражение не соответствует стоке.

    Во втором случае ("3di0789") строка не должна состоять только из цифровых символов. Но так как в строке также есть и буквы, то строка соответствует регулярному выражению, поэтому метод test возвращает значение true.

    При необходимости мы можем собирать комбинации выражений:

    Выражение [дт]о[нм] указывает на те строки, которые могут содержать подстроки "дом", "том", "дон", "тон".

    Флаги выражений

    Флаги позволяют настроить поведение регулярных выражений. Каждый флаг представляет отдельный символ, который ставится в конце регулярного выражения. В JavaScript применяются следующие флаги:

    Флаг global позволяет найти все подстроки, которые соответствуют регулярному выражению. По умолчанию при поиске подстрок регулярное выражение выбирает первую попавшуюся подстроку из строки, которая соответствует выражению. Хотя в строке может быть множество подстрок, которые также соответствуют выражению. Для этого применяется данный флаг в виде символа g в выражениях

    Флаг ignoreCase позволяет найти подстоки, которые соответствуют регулярному выражению, вне зависимости от регистра символов в строке. Для этого в регулярных выражениях применяется символ i

    Флаг multiline позволяет найти подстроки, которые соответствуют регулярному выражению, в многострочном тексте. Для этого в регулярных выражениях применяется символ m

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

    Флаг i. Регистр символов

    Рассмотрим следующий пример:

    Здесь совпадения строки с выражением нет, так как "Мир" отличается от "мир" по регистру. В этом случае надо изменить регулярное выражение, добавив в него свойство ignoreCase :

    Ну и также мы можем использовать сразу несколько свойств:

    Флаг s

    Флаг s или dotAll позволяет сопоставить символ . (точка) с любым символом, в том числе и с разделителем строки. Например, возьмем следующий пример:

    Здесь в строке "hello\nworld" слова "hello" и "hello" разделены переносом строки (например, мы имеем дело с многострочным текстом). Однако, например, мы хотим, чтобы JavaScript не учитывал перенос строки и чтобы данный текст соответствовал регулярному выражению /hello world/ . В этом случае мы можем применить флаг s :

    В выражении /hello.world/s точка означает произвольный символ. Однако без флага s данное выражение не будет соответствовать многострочному тексту.

    Читайте также: