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

Ретроспективная проверка

Опережающие проверки позволяют задавать условия на то, что «идёт после».

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

Синтаксис:

  • Позитивная ретроспективная проверка: , ищет совпадение с при условии, что перед ним ЕСТЬ .
  • Негативная ретроспективная проверка: , ищет совпадение с при условии, что перед ним НЕТ .

Чтобы протестировать ретроспективную проверку, давайте поменяем валюту на доллары США. Знак доллара обычно ставится перед суммой денег, поэтому для того чтобы найти , мы используем – число, перед которым идёт :

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

JavaScript

JS Array
concat()
constructor
copyWithin()
entries()
every()
fill()
filter()
find()
findIndex()
forEach()
from()
includes()
indexOf()
isArray()
join()
keys()
length
lastIndexOf()
map()
pop()
prototype
push()
reduce()
reduceRight()
reverse()
shift()
slice()
some()
sort()
splice()
toString()
unshift()
valueOf()

JS Boolean
constructor
prototype
toString()
valueOf()

JS Classes
constructor()
extends
static
super

JS Date
constructor
getDate()
getDay()
getFullYear()
getHours()
getMilliseconds()
getMinutes()
getMonth()
getSeconds()
getTime()
getTimezoneOffset()
getUTCDate()
getUTCDay()
getUTCFullYear()
getUTCHours()
getUTCMilliseconds()
getUTCMinutes()
getUTCMonth()
getUTCSeconds()
now()
parse()
prototype
setDate()
setFullYear()
setHours()
setMilliseconds()
setMinutes()
setMonth()
setSeconds()
setTime()
setUTCDate()
setUTCFullYear()
setUTCHours()
setUTCMilliseconds()
setUTCMinutes()
setUTCMonth()
setUTCSeconds()
toDateString()
toISOString()
toJSON()
toLocaleDateString()
toLocaleTimeString()
toLocaleString()
toString()
toTimeString()
toUTCString()
UTC()
valueOf()

JS Error
name
message

JS Global
decodeURI()
decodeURIComponent()
encodeURI()
encodeURIComponent()
escape()
eval()
Infinity
isFinite()
isNaN()
NaN
Number()
parseFloat()
parseInt()
String()
undefined
unescape()

JS JSON
parse()
stringify()

JS Math
abs()
acos()
acosh()
asin()
asinh()
atan()
atan2()
atanh()
cbrt()
ceil()
clz32()
cos()
cosh()
E
exp()
expm1()
floor()
fround()
LN2
LN10
log()
log10()
log1p()
log2()
LOG2E
LOG10E
max()
min()
PI
pow()
random()
round()
sign()
sin()
sqrt()
SQRT1_2
SQRT2
tan()
tanh()
trunc()

JS Number
constructor
isFinite()
isInteger()
isNaN()
isSafeInteger()
MAX_VALUE
MIN_VALUE
NEGATIVE_INFINITY
NaN
POSITIVE_INFINITY
prototype
toExponential()
toFixed()
toLocaleString()
toPrecision()
toString()
valueOf()

JS OperatorsJS RegExp
constructor
compile()
exec()
g
global
i
ignoreCase
lastIndex
m
multiline
n+
n*
n?
n{X}
n{X,Y}
n{X,}
n$
^n
?=n
?!n
source
test()
toString()

(x|y)
.
\w
\W
\d
\D
\s
\S
\b
\B
\0
\n
\f
\r
\t
\v
\xxx
\xdd
\uxxxx

JS Statements
break
class
continue
debugger
do…while
for
for…in
for…of
function
if…else
return
switch
throw
try…catch
var
while

JS String
charAt()
charCodeAt()
concat()
constructor
endsWith()
fromCharCode()
includes()
indexOf()
lastIndexOf()
length
localeCompare()
match()
prototype
repeat()
replace()
search()
slice()
split()
startsWith()
substr()
substring()
toLocaleLowerCase()
toLocaleUpperCase()
toLowerCase()
toString()
toUpperCase()
trim()
valueOf()

Алгоритм[править]

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

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

Например, для , очевидно, проще написать простой сопоставитель, чем строить НКА.

Псевдокодправить

function match(regexp: String, text: String): boolean  
    if regexp == '^'
        return matchHere(regexp, text)  
    int i = 0
    while i  text.length
        if matchHere(regexp, text)
            return true
        i++
    return false

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

Логика функции проста. Если — первый символ регулярного выражения, то любое возможное вхождение должно начинаться в начале текста. То есть если — регулярное выражение, то должно входить в текст только с первой позиции текста, а не где-то в середине текста. Это проверяется путем сопоставления остатка регулярного выражения с текстом, начиная с первой позиции и нигде более.

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

function matchHere(regexp: String, text: String): boolean 
    if regexp == '\0'
        return true 
    if regexp == '*'  
        return matchStar(regexp, regexp, text)
    if regexp == '$' and regexp == '\0'
        return text == '\0'
    if text != '\0' and (regexp == '.' or regexp == text)
        return matchHere(regexp, text)
    return false

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

function matchStar(c: char, regexp: String, text: String): boolean
    int i = 0
    while i  text.length and (text == c or c == '.')
        if matchHere(regexp, text)
            return true
        i++
    return false

Рассмотрим возможные случаи:

  1. Если в ходе рекурсии регулярное выражение осталось пустым то текст допускается этим регулярным выражением.
  2. Если регулярное выражение имеет вид , то вызывается функция которая пытается сопоставить повторение символа , начиная с нуля повторений и увеличивая их количество, пока не найдет совпадение с оставшимся текстом. Если совпадение не будет найдено, то регулярное выражение не допускает текст. Текущая реализация ищет «кратчайшее совпадение», которое хорошо подходит для сопоставления с образцом, как в grep, где нужно как можно быстрее найти совпадение. «Наидлиннейшее совпадение» более интуитивно и больше подходит для текстовых редакторов, где найденное заменят на что-то. Большинство современных библиотек для работы с регулярными выражениями предоставляют оба варианта.
  3. Если регулярное выражение это , то оно допускает этот текст тогда и только тогда, когда текст закончился.
  4. Если первый символ текста совпал с первым символом регулярного выражения, то нужно проверить совпадают ли следующий символ регулярного выражения со следующим символом текста, сделав рекурсивный вызов .
  5. Если все предыдущие попытки найти совпадения провалились, то никакая подстрока из текста не допускается регулярным выражением.

Модификацииправить

Немного изменим функцию для поиск самого левого и самого длинного вхождения :

  1. Найдем максимальную последовательность подряд идущих символов . Назовем ее .
  2. Сопоставим часть текста без с остатком регулярного выражения.
  3. Если части совпали, то текст допускается этим регулярным выражением. Иначе, если пусто, то текст не допускается этим регулярным выражением, иначе убираем один символ из и повторяем шаг .

Псевдокодправить

function matchStar(c: char, regexp: String, text: String): boolean
    int i
    for (i = 0; text != '\0' and (text == c or c == '.'); i++)
    while i  0
        if matchHere(regexp, text)
            return true
        i--
    return false

Как правильно писать регулярные выражения ¶

Прежде, чем садиться и писать регулярно выраженного кракена, подумайте, что именно вы хотите сделать. Регулярное выражение должно начинаться с мысли «Я хочу найти/заменить/удалить то-то и то-то». Затем вам нужен исходный текст, который содержит как ПРАВИЛЬНЫЕ, так и НЕправильные данные. Затем вы открываете https://regex101.com/, вставляете текст и начинаете писать регулярное выражение. Этот замечательный инструмент укажет и покажет все ошибки, а также подсветит результаты поиска.

Для примера возьмём валидацию ip-адреса. Первая мысль должна быть: «Я хочу валидировать ip-адрес. А что такое ip-адрес? Из чего он состоит?». Затем нужен список валидных и невалидных адресов:

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

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

Теперь, зная все диапазоны байта, можно объединить их в одно выражение через вертикальную палочку | (ИЛИ):

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

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

Осталось дело за малым: сделать так, чтобы искать четыре байта, а не один. Нужно учесть, что байты разделены тремя точками. То есть мы ищем три байта с точкой на конце и один без точки:

Результат выглядит так:

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

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

Create a RegEx

There are two ways you can create a regular expression in JavaScript.

  1. Using a regular expression literal:
    The regular expression consists of a pattern enclosed between slashes . For example,

    Here, is a regular expression.

  2. Using the constructor function:
    You can also create a regular expression by calling the constructor function. For example,

For example,

In the above example, the string matches with the RegEx pattern . Here, the method is used to check if the string matches the pattern.

There are several other methods available to use with JavaScript RegEx. Before we explore them, let’s learn about regular expressions themselves.

If you already know the basics of RegEx, jump to .

Опережающая проверка

Синтаксис опережающей проверки: .

Он означает: найди при условии, что за ним следует . Вместо и здесь может быть любой шаблон.

Для целого числа, за которым идёт знак , шаблон регулярного выражения будет :

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

Если это не так, то игнорирует совпадение и продолжает поиск дальше

При поиске движок регулярных выражений, найдя , проверяет есть ли после него . Если это не так, то игнорирует совпадение и продолжает поиск дальше.

Возможны и более сложные проверки, например означает:

  1. Найти .
  2. Проверить, идёт ли сразу после (если нет – не подходит).
  3. Проверить, идёт ли сразу после (если нет – не подходит).
  4. Если обе проверки прошли – совпадение найдено.

То есть, этот шаблон означает, что мы ищем при условии, что за ним идёт и и .

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

Например, ищет при условии, что за ним идёт пробел, и где-то впереди есть :

В нашей строке это как раз число .

JavaScript Regular Expression Methods

As mentioned above, you can either use  or regular expression literal to create a RegEx in JavaScript.

In JavaScript, you can use regular expressions with methods:  and .

There are also some string methods that allow you to pass RegEx as its parameter. They are: , , , and .

Method Description
Executes a search for a match in a string and returns an array of information. It returns null on a mismatch.
Tests for a match in a string and returns true or false.
Returns an array containing all the matches. It returns null on a mismatch.
Returns an iterator containing all of the matches.
Tests for a match in a string and returns the index of the match. It returns -1 if the search fails.
Searches for a match in a string and replaces the matched substring with a replacement substring.
Break a string into an array of substrings.

Правила написания шаблонов в JavaScript

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

Итак, flag – это инструмент для установки глобального или регистронезависимого поиска. В JS можно использовать четыре вида флага. При этом вы можете их прописывать как по отдельности, так и комбинировать в разном порядке и количестве. Хочу заметить, что от смены порядка результат выполнение не изменится.

Флаг Предназначение
m Определяет многострочный поиск, т.е. образец сравнивается со всеми буквами, цифрами или другими знаками, которые разделены между собой известными пробельными символами.
i Поиск подстрок осуществляется без учета регистра.
y Выполнение проверки переменных начинается от символа, находящегося на позиции свойства под названием lastIndex.
g Задает глобальный поиск, после выполнения которого будут выведены все возможные совпадения.

Ну а теперь давайте рассмотрим первый простой пример для понимания происходящего. С помощью переменной regExp я проверяю, есть ли вхождение в text слова «вариант». При этом я хочу, чтобы вывелись все случаи вхождения без учета регистра.

1
2
3
4
5
6
<script>
var regExp = /вариант/gi;
var text = "Вариант 1. напишите стих, состоящий из четырех строк. Вариант 2. Допишите стих из варианта 1.";
var myArray = text.match(regExp );
alert(myArray);
</script>

search()

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

// Синтаксис метода search()// 'проверяемый текст'.search(/шаблон/)// Создание текста для проверкиconst myString = 'The world of code is not full of code.'// Описание шаблонаconst myPattern = /code/// Использование search() для поиска//совпадения строки с шаблоном,//когда search() находит совпадениеmyString.search(myPattern)// -13// Вызов search() прямо на строке,// когда search() не находит совпадений'Another day in the life.'.search(myPattern)// -1

Короткие обозначения

Для самых востребованных квантификаторов есть сокращённые формы записи:

Означает «один или более». То же самое, что и .

Например, находит числа (из одной или более цифр):

Означает «ноль или один». То же самое, что и . По сути, делает символ необязательным.

Например, шаблон найдёт после которого, возможно, следует , а затем .

Поэтому шаблон найдёт два варианта: и :

Означает «ноль или более». То же самое, что и . То есть символ может повторяться много раз или вообще отсутствовать.

Например, шаблон находит цифру и все нули за ней (их может быть много или ни одного):

Сравните это с (один или более):

Советы и подсказки

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

var slashSearch = ///;
var questionSearch = /?/;
  • d – это то же самое, что и : каждая конструкция соответствует цифровому символу.
  • w – это то же самое, что : оба выражения соответствуют любому одиночному алфавитно-цифровому символу или подчеркиванию.

Пример: добавляем пробелы в строки, написанные в «верблюжьем» стиле

В этом примере мы очень устали от «верблюжьего» стиля написания и нам нужен способ добавить пробелы между словами. Вот пример:

removeCc('camelCase') // => должен вернуть 'camel Case'

Существует простое решение с использованием регулярного выражения. Во-первых, нам нужно найти все заглавные буквы. Это можно сделать с помощью поиска набора символов и глобального модификатора.

Это соответствует символу «C» в «camelCase»

//g

Теперь, как добавить пробел перед «C»?

Нам нужно использовать захватывающие скобки! Они позволяют найти соответствие и запомнить его, чтобы использовать позже! Используйте захватывающие скобки, чтобы запомнить найденную заглавную букву:

/()/

Получить доступ к захваченному значению позднее можно так:

$1

Выше мы используем $1 для доступа к захваченному значению. Кстати, если бы у нас было два набора захватывающих скобок, мы использовали бы $1 и $2 для ссылки на захваченные значения и аналогично для большего количества захватывающих скобок.

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

Вернемся к текущей задаче. Как мы реализуем захватывающие скобки? С помощью метода JavaScript regexp replace! В качестве второго аргумента мы передаем «$1»

Здесь важно использовать кавычки

function removeCc(str){
  return str.replace(/()/g, '$1');  
}

Снова посмотрим на код. Мы захватываем прописную букву, а затем заменяем ее той же самой буквой. Внутри кавычек вставим пробел, за которым следует переменная $1. В итоге получаем пробел после каждой заглавной буквы.

function removeCc(str){
  return str.replace(/()/g, ' $1');  
}
removeCc('camelCase') // 'camel Case'
removeCc('helloWorldItIsMe') // 'hello World It Is Me'

Пример: удаляем заглавные буквы

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

//g

Мы снова будем использовать метод replace, но как в этот раз сделать строчной символ?

function lowerCase(str){
  return str.replace(//g, ???);  
}

Подсказка: в методе replace() в качестве второго параметра можно указать функцию.

Мы будем использовать стрелочную функцию, чтобы не захватывать значение найденного совпадения. При использовании функции в методе JavaScript regexp replace эта функция будет вызвана после поиска совпадений, и результат функции используется в качестве замещающей строки. Еще лучше, если совпадение является глобальным и найдено несколько совпадений — функция будет вызвана для каждого найденного совпадения.

function lowerCase(str){
  return str.replace(//g, (u) => u.toLowerCase());
}
lowerCase('camel Case') // 'camel case'
lowerCase('hello World It Is Me') // 'hello world it is me'

Пример: преобразуем первую букву в заглавную

capitalize('camel case') // => должен вернуть 'Camel case'

Еще раз воспользуемся функцией в методе replace(). Однако на этот раз нам нужно искать только первый символ в строке. Напомним, что для этого используется символ «^».

Давайте на секунду задержимся на символе «^». Вспомните пример, приведенный ранее:

console.log(/cat/.test('the cat says meow'));
//верно

При добавлении символа «^» функция больше не возвращает значение true, поскольку слово «cat» находится не в начале строки:

console.log(/^cat/.test('the cat says meow'));
//неверно

Мы хотим применить символ «^» к любому строчному символу в начале строки, поэтому мы поместим его перед набором символов . В этом случае JavaScript regexp будет направлено только на первый символ, если это строчная буква.

/^/

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

function capitalize(str){
  return str.replace(/^/, (u) => u.toUpperCase());
}
capitalize('camel case') // 'Camel case'
capitalize('hello world it is me') // 'Hello world it is me'

Упрощённый пример

В чём же дело? Почему регулярное выражение «зависает»?

Чтобы это понять, упростим пример: уберём из него пробелы . Получится .

И, для большей наглядности, заменим на . Получившееся регулярное выражение тоже будет «зависать», например:

В чём же дело, что не так с регулярным выражением?

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

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

Что же происходит во время поиска в строке (укоротим для ясности), почему всё так долго?

  1. Первым делом, движок регулярных выражений пытается найти . Плюс является жадным по умолчанию, так что он хватает все цифры, какие может:

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

    Далее по шаблону ожидается конец строки , а в тексте символ , так что соответствий нет:

  2. Так как соответствие не найдено, то «жадный» квантификатор уменьшает количество повторений, возвращается на один символ назад.

    Теперь – это все цифры, за исключением последней:

  3. Далее движок снова пытается продолжить поиск, начиная уже с позиции ().

    Звёздочка теперь может быть применена – она даёт второе число :

    Затем движок ожидает найти , но это ему не удаётся, ведь строка оканчивается на :

  4. Так как совпадения нет, то поисковый движок продолжает отступать назад. Общее правило таково: последний жадный квантификатор уменьшает количество повторений до тех пор, пока это возможно. Затем понижается предыдущий «жадный» квантификатор и т.д.

    Перебираются все возможные комбинации. Вот их примеры.

    Когда первое число содержит 7 цифр, а дальше число из 2 цифр:

    Когда первое число содержит 7 цифр, а дальше два числа по 1 цифре:

    Когда первое число содержит 6 цифр, а дальше одно число из 3 цифр:

    Когда первое число содержит 6 цифр, а затем два числа:

    …И так далее.

Существует много способов как разбить на числа набор цифр . Если быть точным, их , где – длина набора.

В случае их порядка миллиона, при – ещё в тысячу раз больше. На их перебор и тратится время.

Что же делать?

Может нам стоит использовать «ленивый» режим?

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

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

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

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

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

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

var i = str.search(/\s/)
var i = str.search("\\s")

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

var regText = "\\s"
var i = str.search(new RegExp(regText, "g"))

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

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

Этот пример выводит сообщение, в зависимости от того, подходит ли строка под регулярное выражение.

function testinput(re, str){
   if (str.search(re) != -1)
      midstring = " contains ";
   else
      midstring = " does not contain ";
   document.write (str + midstring + re.source);
}

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

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

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

Если Вы хотите получить первый результат — попробуйте r.

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

str = "For more information, see Chapter 3.4.5.1";
re = /chapter (\d+(\.\d)*)/i;
found = str.match(re);
alert(found);

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

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

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

var str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
var regexp = //gi;
var matches = str.match(regexp);
document.write(matches);

// matches = 

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

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

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

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

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

var ab = "a b".replace("\\s","..") // = "a b"

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

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

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

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

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

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

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

function replacer(str, p1, p2, offset, s)
{
return str + " - " + p1 + " , " + p2;
}
var newString = "XXzzzz".replace(/(X*)(z*)/, replacer)

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

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

function styleHyphenFormat(propertyName)
{
  function upperToHyphenLower(match)
  {
    return '-' + match.toLowerCase();
  }
  return propertyName.replace(//, upperToHyphenLower);
}

МетаСимволы

Для указания регулярных выражений используются метасимволы. В приведенном выше примере ( ) является метасимволом.

Метасимволы — это символы, которые интерпретируются особым образом механизмом RegEx. Вот список метасимволов:

[]. ^ $ * +? {} () \ |

— Квадратные скобки

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

Выражение Строка Совпадения
1 совпадение
2 совпадения
Не совпадает
5 совпадений

Здесь будет соответствовать, если строка, которую вы пытаетесь сопоставить, содержит любой из символов , или .

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

то же самое, что и .

то же самое, что и .

то же самое, что и .

Вы можете дополСтрока (инвертировать) набор символов, используя символ вставки в начале квадратной скобки.

означает любой символ, кроме или или .

означает любой нецифровой символ.

— Точка

Точка соответствует любому одиночному символу (кроме новой строки ).

Выражение Строка Совпадения
Не совпадает
1 совпадение
1 совпадение
2 совпадения (содержит 4 символа)

— Каретка

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

Выражение Строка Совпадения
1 совпадение
1 совпадение
Не совпадает
1 совпадение
Нет совпадений (начинается с , но не сопровождается )

— доллар

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

Выражение Строка Совпадения
1 совпадение
1 совпадение
Не совпадает

— Звездочка

Символ звездочки соответствует предыдущему символу повторенному 0 или более раз. Эквивалентно {0,}.

Выражение Строка Совпадения
1 совпадение
1 совпадение
1 совпадение
Нет совпадений ( не следует )
1 совпадение

— Плюс

Символ плюс соответствует предыдущему символу повторенному 1 или более раз. Эквивалентно {1,}.

Выражение Строка Совпадения
Нет совпадений (нет символа)
1 совпадение
1 совпадение
Нет совпадений ( не следует )
1 совпадение

— Вопросительный знак

Знак вопроса соответствует нулю или одному вхождению предыдущего символа. То же самое, что и {0,1}. По сути, делает символ необязательным.

Выражение Строка Совпадения
1 совпадение (0 вхождений а)
1 совпадение
Нет совпадений (более одного символа)
Нет совпадений ( не следует )
1 совпадение

— Фигурные скобки

Рассмотрим следующий код: . Это означает, по крайней мере , и не больше повторений предыдущего символа. При m=n=1 пропускается..

Выражение Строка Совпадения
Не совпадает
1 совпадение (в )
2 совпадения (при и )
2 совпадения (при и )

Посмотрим еще один пример. Это RegEx соответствует как минимум 2 цифрам, но не более 4-х цифр.

Выражение Строка Совпадения
1 совпадение (совпадение в )
3 совпадения ( , , )
Не совпадает

— Альтернация (или)

Альтернация (вертикальная черта) – термин в регулярных выражениях, которому в русском языке соответствует слово «ИЛИ». (оператор ).

Например: gr(a|e)y означает точно то же, что и gry.

Выражение Строка Совпадения
Не совпадает
1 совпадение (совпадение в )
3 совпадения (в )

Здесь сопоставьте любую строку, содержащую либо, либо

Чтобы примеСтрока альтернацию только к части шаблона, можно заключить её в скобки:

  • найдёт или .
  • найдёт или .

— Скобочные группы

Круглые скобки используются для группировки подшаблонов. Так, например, соответствует любой строке, которая соответствует либо или или с последующим

Выражение Строка Совпадения
Не совпадает
1 совпадение (совпадение в )
2 совпадения (в )

— обратная косая черта

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

соответствует, если строка содержит , за которым следует . Здесь механизм RegEx не интерпретирует особым образом.

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

Квантификаторы

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

/* Квантификатор - Значение */* - 0 или более совпадений с предшествующим выражением.+ - 1 или более совпадений с предшествующим выражением.? - Предшествующее выражение необязательно (то есть совпадений 0 или 1).x{n} - "n" должно быть целым положительным числом. Количество вхождений предшествующего выражения "x" равно "n".x{n, } - "n" должно быть целым положительным числом. Количество вхождений предшествующего выражения "x" равно, как минимум, "n".x{n, m} - "n" может быть равно 0 или целому положительному числу. "m" - целое положительное число. Если "m" > "n", количество вхождений предшествующего выражения "x" равно минимум "n" и максимум "m".

Примеры:

// * - 0 или более совпадений с предшествующим выражениемconst myPattern = /bo*k/console.log(myPattern.test('b'))// falseconsole.log(myPattern.test('bk'))// trueconsole.log(myPattern.test('bok'))// true// + - 1 или более совпадений с предшествующим выражениемconst myPattern = /\d+/console.log(myPattern.test('word'))// falseconsole.log(myPattern.test(13))// true// ? - Предшествующее выражение необязательно, совпадений 0 или 1const myPattern = /foo?bar/console.log(myPattern.test('foobar'))// trueconsole.log(myPattern.test('fooobar'))// false// x{n} - Количество вхождений предшествующего выражения "x" равно "n"const myPattern = /bo{2}m/console.log(myPattern.test('bom'))// falseconsole.log(myPattern.test('boom'))// trueconsole.log(myPattern.test('booom'))// false// x{n, } - Количество вхождений предшествующего выражения "x" равно, как минимум, "n"const myPattern = /do{2,}r/console.log(myPattern.test('dor'))// falseconsole.log(myPattern.test('door'))// trueconsole.log(myPattern.test('dooor'))// true// x{n, m} - Количество вхождений предшествующего выражения "x" равно минимум "n" и максимум "m"const myPattern = /zo{1,3}m/console.log(myPattern.test('zom'))// falseconsole.log(myPattern.test('zoom'))// trueconsole.log(myPattern.test('zooom'))// trueconsole.log(myPattern.test('zoooom'))// false

Выводы, рецепты

Будет намного проще понять методы JavaScript RegExp, если мы разделим их по использованию на практике.

Чтобы найти только первое совпадение:

  • Найти позицию первого совпадения – str.search(reg);
  • Найти полное совпадение – str.match(reg);
  • Проверить, есть ли совпадение – regexp.test(str);
  • Найти совпадение с заданной позиции – regexp.exec(str), установите regexp.lastIndex в номер позиции.

Чтобы найти все совпадения:

  • Массив совпадений – str.match(reg), регулярное выражение с флагом g;
  • Получить все совпадения с полной информацией о каждом из них – regexp.exec(str) с флагом g в цикле.

Чтобы найти и заменить:

Заменить одну строку на другую или результат работы функции – str.replace(reg, str|func).

Чтобы разделить строку:

str.split(str|reg).

Кроме этого мы изучили два флага JavaScript RegExp:

  • Флаг g — чтобы найти все совпадения (глобальный поиск);
  • Флаг y — чтобы искать на точно заданной позиции внутри текста.

Теперь мы знаем методы и можем использовать регулярные выражения.

Данная публикация является переводом статьи «Methods of RegExp and String» , подготовленная редакцией проекта.

Заключение

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

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

Оригинал статьи: https://code.tutsplus.com/tutorials/a-simple-regex-cheat-sheet—cms-31278/

Перевод: Земсков Матвей

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector