Основы регулярных выражений в javascript

Содержание:

Создание простого регулярного выражения и флаги

Для тестирования и написания паттернов в режиме онлайн я обычно использую сервис https://regex101.com. Выбираете там Javascript и смотрите в риалтайме, как обрабатывается текст вашей регуляркой, плюс там есть подсказки и небольшой справочник. 

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

// Стандартный метод
var re = new RegExp("паттерн", "флаги");

// Укороченная форма записи
var re = /паттерн/; // без флагов
var re = /паттерн/gmi; // с флагами gmi

Флаги — это параметры поиска, их всего несколько видов и вы можете использовать любой из них, или даже все сразу.i — ignore case, Если этот флаг есть, то регэксп ищет независимо от регистра, то есть не различает между А и а.g — global match, Если этот флаг есть, то регэксп ищет все совпадения, иначе – только первое.m — multiline, Многострочный режим.

Пример использования:

var str = 'Писать ботов на iMacros+JS очень круто!';

window.console.log(/imacros/i.test(str)); // true
window.console.log(/imacros/.test(str)); // false

Улучшена поддержка юникода

Внутренняя кодировка строк в JavaScript – это UTF-16, то есть под каждый символ отводится ровно два байта.

Но под всевозможные символы всех языков мира 2 байт не хватает. Поэтому бывает так, что одному символу языка соответствует два юникодных символа (итого 4 байта). Такое сочетание называют «суррогатной парой».

Самый частый пример суррогатной пары, который можно встретить в литературе – это китайские иероглифы.

Заметим, однако, что не всякий китайский иероглиф – суррогатная пара. Существенная часть «основного» юникод-диапазона как раз отдана под китайский язык, поэтому некоторые иероглифы – которые в неё «влезли» – представляются одним юникод-символом, а те, которые не поместились (реже используемые) – двумя.

Например:

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

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

Ими представлены редкие математические символы, а также некоторые символы для эмоций, к примеру:

В современный JavaScript добавлены методы String.fromCodePoint и str.codePointAt – аналоги и , корректно работающие с суррогатными парами.

Например, считает суррогатную пару двумя разными символами и возвращает код каждой:

…В то время как возвращает его Unicode-код суррогатной пары правильно:

Метод корректно создаёт строку из «длинного кода», в отличие от старого .

Например:

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

Есть и ещё синтаксическое улучшение для больших Unicode-кодов.

В JavaScript-строках давно можно вставлять символы по Unicode-коду, вот так:

Синтаксис: , где – четырёхзначный шестнадцатиричный код, причём он должен быть ровно четырёхзначным.

«Лишние» цифры уже не войдут в код, например:

Чтобы вводить более длинные коды символов, добавили запись , где – максимально восьмизначный (но можно и меньше цифр) код.

Например:

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

Например, на основе обычного символа существуют символы: . Самые часто встречающиеся подобные сочетания имеют отдельный юникодный код. Но отнюдь не все.

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

Например, если после символа идёт символ «точка сверху» (код ), то показано это будет как «S с точкой сверху» .

Если нужен ещё значок над той же буквой (или под ней) – без проблем. Просто добавляем соответствующий символ.

К примеру, если добавить символ «точка снизу» (код ), то будет «S с двумя точками сверху и снизу» .

Пример этого символа в JavaScript-строке:

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

Вот пример:

В первой строке после основы идёт сначала значок «верхняя точка», а потом – нижняя, во второй – наоборот. По кодам строки не равны друг другу. Но символ задают один и тот же.

С целью разрешить эту ситуацию, существует юникодная нормализация, при которой строки приводятся к единому, «нормальному», виду.

В современном JavaScript это делает метод str.normalize().

Забавно, что в данной конкретной ситуации приведёт последовательность из трёх символов к одному: \u1e68 (S с двумя точками).

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

Для большинства практических задач информации, данной выше, должно быть вполне достаточно, но если хочется более подробно ознакомиться с вариантами и правилами нормализации – они описаны в приложении к стандарту юникод Unicode Normalization Forms.

Группировка

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

Например, в regexp квантификатор применяется только к последнему символу o и соответствует строкам «go», «goo» и так далее. В регулярном выражении квантификатор применяется к группе символов и и соответствует строкам «go», «gogo» и т. д.

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

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

Используем флаги в регулярных выражениях

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

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

i – делает поиск нечувствительным к регистру. В этом случае такие слова, как “Apple”, “aPPLe” и “apple” попадут в результаты поиска;

m – флаг включает многострочный поиск;

u – этот флаг позволит вам использовать в вашем регулярном выражении escape-последовательности кода Unicode;

y – Указывает JavaScript вести поиск соответствия в текущей позиции в целевой строке;

Флаги для регулярного выражения в JavaScript можно использовать 2 способами: либо путем добавления их в конец литерала регулярных выражений, либо путем передачи их в конструктор RegExp. Например, /cat/i, соответствующее всех вхождениям слова “cat” независимо от регистра и RegExp(«cat», ‘i’) будут работать одинаково.

test()

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

// Синтаксис метода test()// /шаблон/.test('проверяемый текст')// Проверка строки,// когда test() не находит совпаденийmyPattern.test('There was a cat and dog in the house.')// false// Создание переменной,// которой присваивается текст для проверкиconst myString = 'The world of code.'// Создание шаблонаconst myPattern = /code/// Проверка текста с помощью шаблона,// когда test() находит совпадениеmyPattern.test(myString)// true

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

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

Все методы, кроме 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);
}

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

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

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

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

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

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

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

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

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

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

Классы символов

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

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

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

RegExp Что оно делает
Соответствует любому из символов a, b или c.
Соответствует любому одному символу, кроме a, b или c.
Соответствует любому символу от строчной буквы a до строчной буквы z.
Соответствует любому символу от прописных букв A до прописных букв Z.
Соответствует любому символу от строчной буквы a до прописной буквы Z.
Соответствует одной цифре от 0 до 9.
Соответствует одному символу между a и z или между 0 и 9.

В следующем примере показано, как определить, существует ли шаблон в строке или нет, используя регулярное выражение с методом JavaScript :

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

Регулярные выражения не являются исключительными для JavaScript. Такие языки, как Java, Perl, Python, PHP и т. д., используют одинаковые обозначения для поиска шаблонов в тексте.

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()

Общие сведения о регулярных выражениях в JavaScript

Регулярные выражения появились в JavaScript 1.2 и JScript 3.0 вместе с объектом RegExp, поскольку соответствующие возможности реализуются посредством методов RegExp. Однако и многие методы объекта String допускают использование регулярных выражений в качестве аргументов, поэтому регулярные выражения часто встречаются в обоих указанных контекстах.

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

1 varpattern=/http/;

Этот шаблон читается так: за » h » следует » t», затем » t», а затем » р «. Этому шаблону будет соответствовать любая строка, содержащая «http». Непосредственно за второй косой чертой шаблона можно указать флаги, модифицирующие интерпретацию шаблона. Например, указать, что шаблон должен применяться без учета регистра, — для этого используется флаг i:

1 varpatternlgnoringCase=/http/i;

Здесь создается шаблон, которому будут соответствовать строки, содержащие как «http», так и «HTTP» или «HttP». Флаги, наиболее часто используемые с регулярными выражениями, показаны в табл. , а их применение будет иллюстрироваться в примерах данной главы. Пока что не беспокойтесь ни о чем, кроме i.

Символ Значение
i Нечувствительность к регистру
g Глобальное соответствие: находятся все случаи соответствия в строке, а не только первый
m Многострочное соответствие

Регулярные выражения могут также объявляться с помощью конструктора RegExp(). Первый аргумент конструктора — это строка, содержащая требуемый шаблон. Второй аргумент необязателен, он содержит специальные флаги для этого выражения. Два предложенных выше примера шаблонов можно было бы объявить так:

1
2

varpattern=newRegExp(«http»);

varpatternlgnoringCase=newRegExp(«http»,»i»);

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

1
2

varpattern=newRegExp(«http»);

pattern.test(«HTTP://WWW.W3C.ORG/»);

возвратит false, поскольку шаблону соответствуют только строки, содержащие «http». Но можно проверить соответствие шаблону без учета регистра:

1
2

varpatternlgnoringCase=newRegExp(«http»,»i»);

patternlgnoringCase.test(«HTTP://WWW.W3C.ORG/»);

Тогда будет возвращено true, поскольку в данном случае поиск соответствия «http» в строке выполняется без учета регистра. Конечно, результата вы не увидите, пока не используете возвращаемое значение:

1
2

varpatternlgnoringCase=newRegExp(«http»,»i»);

alert(patternlgnoringCase.test(«HTTP://WWW.W3C.ORG/»));

Автоматическое преобразование типов в JavaScript позволяет вызывать методы RegExp с литералами регулярных выражений (аналогично методам String с литералами строк). Например,

1 alert(/http/i.test(«HTTP://WWW.W3C.ORG/»));

точно так же покажет true.

Правила написания шаблонов в 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>

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

exec(regexp) — находит все совпадения (вхождения в шаблон «регулярки») в строке. Возвращает массив (при совпадении) и обновляет свойство regexp-а, или null — если ничего не найдено,.
С модификатором g — при каждом вызове этой функции, она будет возвращать следующее совпадение после предыдущего найденного — это реализовано с помощью ведения индекса смещения последнего поиска.

match(regexp) — найти часть строки по шаблону. Если указан модификатор g, то функция match() возвращает массив всех совпадений или null (а не пустой массив). Без модификатора g эта функция работает как exec();

test(regexp) — функция проверяет строку на соответствие шаблону. Возвращает true — если есть совпадение, и false — если совпадения нет.

replace(regexp, mix) — метод возвращает строку изменную в соответствии с шаблоном (регуляррным выражением). Первый параметр regexp также может содержать строку, а не регулярное выражение. Без модификатора g — метод в строке заменяет только первое вхождение; с модификатором g — происходит глобальная замена, т.е. меняются все вхождения в данной строке. mix — шаблон замены, может принитать значения строки, шаблона замены, функции (имя функции).

Стоит подробнее остановиться на методе replace(), его второй параметр mix нужно описать более детально.

Если второй параметр mix содержит строку, то мы можем использовать следующие спецсимволы:

  • $$ — вставить $;
  • $& — совпавшая подстрока;
  • $` — часть строки перед совпавшей подстроки;
  • $’ — часть строки после совпавшей подстроки;
  • $n ($nn) — значение n-ой запоминающей скобки (если первый аргумент — объект RegExp);

Если второй параметр mix содержит функцию, то она будет вызванна при каждом совпадении. Значением для замены будет результат работы функции, т.е. return »;

Примеры таких функции:

Следующий вызов replace возвратит XXzzzz — XX , zzzz.

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

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

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

Таким блоком кода я разбираю javascript вхождения в html:

Класс RegExp

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

RegExp(Регулярное выражение, Флаги)

Он принимает только один обязательный пареметр — это «Регулярное выражение», которое заключается в кавычки.
Параметр «флаги» представляет собой дополнительные условия поиска и может принимать значения:

  • g — задается глобальный поиск, если этот флаг установлен, то выражение возвратит все подходящие слова.
  • i — игнорирование регистра символов
  • m — многострочный поиск

Для работы с регулярными варажениями используются три метода класса String:

  • match — выполняет поиск в строке, используя регулярное выражение, переданное в качестве параметра
    и возвращает массив с результатами поиска. Если ничего не найдено, возвращается null.
  • replace — выполняет поиск и замену в строке, используя регулярные выражения, и возвращает полученную строку.
  • search — выполняет поик в строке, используя регулярное выражение, переданное в качестве параметра,
    и возвращает позицию первой подстроки, совпадающей с регулярным выражением.

Свойства

Свойство Описание
lastIndex Задает позицию начала поиска в строке
sourse Возвращает строку регулярного выражения (только чтение)
global Определяет наличие флага g и возвращает соответсявенно true или false
ignoreCase Определяет наличие флага i и возвращает соответсявенно true или false
multilane Определяет наличие флага m и возвращает соответсявенно true или false

Методы

Метод Описание
compile (Регулярное выражение g,i,m) Компилирует регулярное выражение во внутренний формат для ускорения работы, может использоваться для изменения регулярного выражения
exec(строка) Аналогичен методу match класса String, но строка, где нужно произвести поиск, передается в качестве параметра
test(строка) Аналогичен методу search класса String, возвращает true или false в зависимости о результатов поиска

Пример

Здесь этот участок скрипта производит поиск текста «www» в строке, которая была присвоена переменной «str» без учета регистра,
а метод match возвращает массив result, содержащий результаты поиска.

Точка и перенос строки

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

И javascript здесь не исключение.

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

function bbtagit(text) {
  text = text.replace(/\(.*?)\[\/u\]/gim, '<u>$1</u>')
 
  return text
}

var line = "мой\n текст"
alert( bbtagit(line) )

Попробуйте запустить. Заменяет? Как бы не так!

Дело в том, что в javascript мультилайн режим (флаг ) влияет только на символы ^ и $, которые начинают матчиться с началом и концом строки, а не всего текста.

Точка по-прежнему — любой символ, кроме новой строки. В javascript нет флага, который устанавливает мультилайн-режим для точки. Для того, чтобы заматчить совсем что угодно — используйте .

Работающий вариант:

function bbtagit(text) {
  text = text.replace(/\(*)\[\/u\]/gim, '<u>$1</u>')
 
  return text
}

var line = "мой\n текст"
alert( bbtagit(line) )

Ещё примеры

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

Регулярное выражение для десятичных дробей (чисел с плавающей точкой):

В действии:

Регулярное выражение для «открывающего HTML-тега без атрибутов», например, или .

  1. Самое простое:

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

  2. Улучшенное:

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

Регулярное выражение для «открывающего или закрывающего HTML-тега без атрибутов»:

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

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

В этих примерах мы видим общее правило: чем точнее регулярное выражение – тем оно длиннее и сложнее.

Например, для HTML-тегов без атрибутов, скорее всего, подошло бы и более простое регулярное выражение: . Но стандарт HTML накладывает более жёсткие ограничения на имя тега, так что более точным будет шаблон .

Подойдёт ли нам или нужно использовать ? А, может быть, нужно ещё его усложнить, добавить атрибуты?

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

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

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

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

Синтаксис:

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

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

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

Статические свойства

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

Вот — одна интересная функция.

Запустите ее один раз, запомните результат — и запустите еще раз.

function rere() {
    var re1 = /0/, re2 = new RegExp('0')
    alert()
    re1.foo = 1
    re2.foo = 1
}
rere()

В зависимости от браузера, результат первого запуска может отличаться от второго. На текущий момент, это так для Firefox, Opera. При этом в Internet Explorer все нормально.

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

Почему же разный результат?

Ответ кроется в стандарте ECMAScript, :

Цитата…

A regular expression literal is an input element that is converted to a RegExp object (section 15.10)
when it is scanned. The object is created before evaluation of the containing program or function begins.
Evaluation of the literal produces a reference to that object; it does not create a new object.

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

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

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

Будет намного проще понять методы 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 — чтобы искать на точно заданной позиции внутри текста.

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

Пожалуйста, оставьте ваши комментарии по текущей теме материала. За комментарии, лайки, подписки, отклики, дизлайки низкий вам поклон!

Итого

Существуют следующие символьные классы:

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

…Но это не всё!

В кодировке Юникод, которую JavaScript использует для строк, каждому символу соответствует ряд свойств, например – какого языка это буква (если буква), является ли символ знаком пунктуации, и т.п.

Можно искать, в том числе, и по этим свойствам. Для этого нужен флаг , который мы рассмотрим в следующей главе.

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

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