Проверка данных регулярными выражениями в php

Содержание:

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

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

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

Альтернативы¶

Выражения в списке альтернатив разделяются .

Таким образом, будет соответствовать любому из , или (также как и ).

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

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

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

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

Также помните, что в квадратных скобках воспринимается просто как символ, поэтому, если вы напишите , это тоже самое что .

Абстрактные операции для конструктора RegExp

  • 22.2.3.2.1
  • 22.2.3.2.2
  • 22.2.3.2.3
  • 22.2.3.2.4
  • 22.2.3.2.5

22.2.3.2.1 RegExpAlloc ( newTarget )

Абстрактная операция RegExpAlloc (Распределение регулярного выражения) принимает аргумент newTarget. При вызове она выполняет следующие шаги:

1. Пусть obj будет ? (newTarget, "%RegExp.prototype%", «`RegExpMatcher`, `OriginalSource`, `OriginalFlags`»).
2. Выполнить ! (obj, "lastIndex", PropertyDescriptor {`Writable`: true, `Enumerable`: false, `Configurable`: false}).
3. Вернуть obj.

22.2.3.2.2 RegExpInitialize ( obj, pattern, flags )

1. Если шаблон pattern является undefined(не определен), пусть P будет пустой строкой.
2. Иначе пусть P будет ? (pattern).
3. Если flags является undefined(не определен), пусть F будет пустой строкой.
4. Иначе пусть F будет ? (flags).
5. Если F содержит любую кодовую единицу, кроме «g», «i», «m», «s», «u» или «y», или если она содержит одну и ту же кодовую единицу более одного раза, бросить исключение SyntaxError.
6. Если F содержит «u», пусть u будет true (истинно); иначе пусть u будет false (ложь).
7. Если u является true (истинно), то
   а. Пусть patternText будет ! (P).
   b. Пусть patternCharacters будет , элементы которого являются кодовыми точками patternText.
8. Иначе,
   а. Пусть patternText будет результатом интерпретации каждого из 16-битных элементов P как кодовой точки Unicode BMP. К элементам не применяется декодирование UTF-16.
   b. Пусть patternCharacters будет списком , элементы которого являются элементами кодовой единицы P.
9. Пусть parseResult будет (patternText, u).
10. Если parseResult является непустым списком объектов SyntaxError, вызовите исключение SyntaxError.
11. : parseResult - это  для шаблона .
12. Установите для obj.`OriginalSource` значение P.
13. Установите для obj.`OriginalFlags` значение F.
14. Установите для obj.`RegExpMatcher` , которое оценивает parseResult, применяя семантику, представленную в , используя patternCharacters в качестве списка значений  шаблона и F в качестве параметров флага.
15. Выполнить ? установить (obj, "lastIndex", +0?, true).
16. Вернуть объект obj.

22.2.3.2.3 Static Semantics: ParsePattern ( patternText, u )

Абстрактная операция ParsePattern (Синтаксический анализ шаблона) принимает аргументы patternText (последовательность кодовых точек Unicode) и u (логическое значение). При вызове она выполняет следующие шаги:

1. Если u является true (истинно, то
а. Пусть parseResult будет (patternText,  ).
2. Иначе,
   а. Пусть parseResult будет (patternText,  ).
   b. Если parseResult является , а parseResult содержит , тогда
      i. Установите parseResult в (patternText,  ).
3. Верните parseResult.

22.2.3.2.4 RegExpCreate ( P, F )

Абстрактная операция RegExpCreate (Создать регулярное выражение) принимает аргументы P и F. При вызове она выполняет следующие шаги:

1. Пусть obj будет ? ().
2. Вернуть ? (obj , P, F).

22.2.3.2.5 EscapeRegExpPattern ( P, F )

Абстрактная операция EscapeRegExpPattern (Экранирующий шаблон регулярного выражения) принимает аргументы P и F. При вызове она выполняет следующие шаги:

1. Пусть S будет строкой в ​​форме   ( , если F содержит "u"), эквивалентной P, интерпретируемой как кодовые точки Unicode в кодировке UTF-16 (), в которых некоторые кодовые точки экранируются, как описано ниже. S может быть или не быть идентичным P; однако , которое будет результатом оценки S как   ( , если F содержит "u"), должно вести себя идентично , заданному внутренним слотом `RegExpMatcher` построенного объекта. Множественные вызовы этой абстрактной операции с использованием одинаковых значений для P и F должны давать одинаковые результаты.
2. Кодовые точки  или любой , встречающийся в шаблоне, должен быть экранирован в S по мере необходимости, чтобы гарантировать, что  «», S, «» и F может быть синтаксически проанализирована (в соответствующем лексическом контексте), как , который ведет себя идентично построенному регулярному выражению. Например, если P равно «», тогда S может быть «\ /» или «\u002F», среди других возможностей, но не «», потому что ///, за которым следует F, будет анализироваться как , а не как . Если P - пустая строка, эта спецификация может быть удовлетворена, если S будет "(?:)".
3. Верните S.

Кванторы

Частоту или положение заключенных в скобки символьных последовательностей и одиночных символов можно обозначить специальным символом. Каждый особый персонаж имеет конкретную коннотацию. +, * ,? , {int. range} и $ flags следуют за символьной последовательностью.

# Значение Описание
р + Он соответствует любой строке, содержащей хотя бы один p.
п* Он соответствует любой строке, содержащей ноль или более p.
p ? Он соответствует любой строке, содержащей ноль или более p. Это просто альтернативный способ использования p *.
р {N} Он соответствует любой строке, содержащей последовательность из N p
р {2,3} Он соответствует любой строке, содержащей последовательность из двух или трех p.
p {2,} Он соответствует любой строке, содержащей последовательность не менее двух p.
р $ Он соответствует любой строке с p в конце ее.
^ р Он соответствует любой строке с p в начале ее.

Примеры

Следующие примеры дают понятия о совпадении символов.

Значение Описание
Он соответствует любой строке, не содержащей ни одного символа в диапазоне от a до z и от A до Z.
p.p Он соответствует любой строке, содержащей p, за которой следует любой символ, в свою очередь, за которым следует другой p.
^. {2} $ Он соответствует любой строке, содержащей ровно два символа.
(.*). Он соответствует любой строке, заключенной внутри b и / b.
p ( hp ) * Он соответствует любой строке, содержащей ap, а затем ноль или более экземпляров последовательности php.

Группировка

Группы (подмаски) в регулярных выражениях делаются с помощью метасимвола группировки .

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

Пример

Поробуй сам

Результат выполнения кода:

1

Ещё примеры:

Выражение Описание
^{1,}$ Любое слово, хотя бы одна буква, число или
+@ Соответствует строке с символом @ в начале, за которым следует любая буква нижнего регистра, число от 0 до 9 или буква верхнего регистра.
()() wy, wz, xy, или xz
+ Один или более символов нижнего регистра

Практические упражнения по регулярным выражениям PHP.

Назад
Вперёд

Освойте PHP и MySQL с нуля в игровой форме
На рынке не хватает веб-разработчиков
На рынке не хватает веб-разработчиков
Освойте популярный PHP-фреймворк
На рынке не хватает fullstack-разработчиков!
Обучение в рассрочку
Учитесь сейчас, платите потом!
Учитесь сейчас, платите потом!

Что такое “жадное” соответствие в регулярных выражениях?

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

Давайте рассмотрим пример фрагмента HTML, где нам необходимо получить тэг HTML.

Вместо совпадения до первого появления ‘>’, которое, должно было произойти в конце первого тэга тела, он извлек всю строку. Это по умолчанию “жадное” соответствие, присущее регулярным выражениям.

С другой стороны, ленивое соответствие “берет как можно меньше”. Это можно задать добавлением в конец шаблона.

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

Regular Expression — Documentation

Metacharacters

Character What does it do?
\
  • Used to indicate that the next character should NOT be interpreted literally. For example, the character ‘w’ by itself will be interpreted as
    ‘match the character w’, but using ‘\w’ signifies ‘match an alpha-numeric character including underscore’.
  • Used to indicate that a metacharacter is to be interpreted literally. For example, the ‘.’ metacharacter means ‘match any single character but a new line’, but if
    we would rather match a dot character instead, we would use ‘\.’.
^
  • Matches the beginning of the input. If in multiline mode, it also matches after a line break character, hence every new line.
  • When used in a set pattern (), it negates the set; match anything not enclosed in the brackets
$ Matches the end of the input. If in multiline mode, it also matches before a line break character, hence every end of line.
* Matches the preceding character 0 or more times.
+ Matches the preceding character 1 or more times.
?
  • Matches the preceding character 0 or 1 time.
  • When used after the quantifiers *, +, ? or {}, makes the quantifier non-greedy; it will match
    the minimum number of times as opposed to matching the maximum number of times.
. Matches any single character except the newline character.
(x) Matches ‘x’ and remembers the match. Also known as capturing parenthesis.
(?:x) Matches ‘x’ but does NOT remember the match. Also known as NON-capturing parenthesis.
x(?=y) Matches ‘x’ only if ‘x’ is followed by ‘y’. Also known as a lookahead.
x(?!y) Matches ‘x’ only if ‘x’ is NOT followed by ‘y’. Also known as a negative lookahead.
x|y Matches ‘x’ OR ‘y’.
{n} Matches the preceding character exactly n times.
{n,m} Matches the preceding character at least n times and at most m times. n and m can be omitted if zero..
Matches any of the enclosed characters. Also known as a character set.
You can create range of characters using the hyphen character such as A-Z (A to Z). Note that in character sets,
special characters (., *, +) do not have any special meaning.
Matches anything NOT enclosed by the brackets. Also known as a negative character set.
Matches a backspace.
\b Matches a word boundary. Boundaries are determined when a word character is NOT followed or NOT preceeded with another word character.
\B Matches a NON-word boundary. Boundaries are determined when two adjacent characters are word characters OR non-word characters.
\cX Matches a control character. X must be between A to Z inclusive.
\d Matches a digit character. Same as or .
\D Matches a NON-digit character. Same as or .
\f Matches a form feed.
\n Matches a line feed.
\r Matches a carriage return.
\s Matches a single white space character. This includes space, tab, form feed and line feed.
\S Matches anything OTHER than a single white space character. Anything other than space, tab, form feed and line feed.
\t Matches a tab.
\v Matches a vertical tab.
\w Matches any alphanumeric character incuding underscore. Equivalent to .
\W Matches anything OTHER than an alphanumeric character incuding underscore. Equivalent to .
\x A back reference to the substring matched by the x parenthetical expression. x is a positive integer.
\0 Matches a NULL character.
\xhh Matches a character with the 2-digits hexadecimal code.
\uhhhh Matches a character with the 4-digits hexadecimal code.

Практические примеры сложных регулярных выражений

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

1) Проверка имени пользователя с помощью регулярного выражения
Начнем с проверки имени пользователя. Если у вас есть форма регистрации, вам понадобится проверять на правильность имена пользователей. Предположим, вы не хотите, чтобы в имени были какие-либо специальные символы, кроме «» и, конечно, имя должно содержать буквы и возможно цифры. Кроме того, вам может понадобиться контролировать длину имени пользователя, например от 4 до 20 символов.

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

После этого нам нужно ограничить количество символов следующим кодом:

{4,20}

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

^{4,20}$

В случае Perl-совместимого регулярного выражения заключите его символами ‘‘. Итоговый PHP-код выглядит так:

<?php
$pattern  = '/^{4,20}$/';
$username = "demo_user-123";
if (preg_match($pattern, $username)) {
 echo "Проверка пройдена успешно!";
} else {
 echo "Проверка не пройдена!";
}
?>

2) Проверка шестнадцатеричного кода цвета регулярным выражением
Шестнадцатеричный код цвета выглядит так: , также допустимо использование краткой формы, например . В обоих случаях код цвета начинается с и затем идут ровно 3 или 6 цифр или букв от a до f.

Итак, проверяем начало кода:

^#

Затем проверяем диапазон допустимых символов:

После этого проверяем допустимую длину кода (она может быть либо 3, либо 6). Полный код регулярного выражения выйдет следующим:

^#(({3}$)|({6}$))

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

<?php
$pattern = '/^#(({3}$)|({6}$))/';
$color   = "#1AA";
if (preg_match($pattern, $color)) {
 echo "Проверка пройдена успешно!";
} else {
 echo "Проверка не пройдена!";
}
?>

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

john.doe@test.com
john@demo.ua
john_123.doe@test.info

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

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

^+

Доменное имя всегда имеет, скажем, имя и tld (top-level domain) – т.е, доменную зону. Доменная зона – это , , и тому подобное. Это означает, что шаблон регулярного выражения для домена будет выглядеть так:

+\.{2,5}$

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

^+@+\.{2,5}$

В коде PHP эта проверка будет выглядеть следующим образом:

<?php
$pattern = '/^+@+\.{2,5}$/';
$email   = "john_123.doe@test.info";
if (preg_match($pattern, $email)) {
 echo "Проверка пройдена успешно!";
} else {
 echo "Проверка не пройдена!";
}
?>

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

  • 3208

  • 35

  • Опубликовано 16/04/2019

  • PHP, Уроки программирования

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

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

Например,

// Найти одну d, за которой следует 1 или более b, за которыми одна d
// Запомнить найденные b и следующую за ними d
// Регистронезависимый поиск
var myRe = /d(b+)(d)/ig;
var myArray = myRe.exec("cdbBdbsbz");

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

Объект Свойство/Индекс Описания Пример
Содержимое .
Индекс совпадения (от 0)
Исходная строка.
Последние совпавшие символы
Совпадения во вложенных скобках, если есть. Число вложенных скобок не ограничено.
Индекс, с которого начинать следующий поиск.
Показывает, что был включен регистронезависимый поиск, флаг «».
Показывает, что был включен флаг «» поиска совпадений.
Показывает, был ли включен флаг многострочного поиска «».
Текст паттерна.

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

var myRe = /ab*/g;
var str = "abbcdefabh";
while ((myArray = myRe.exec(str)) != null) {
	var msg = "Found " + myArray + ".  ";
	msg += "Next match starts at " + myRe.lastIndex;
	print(msg);
}

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

Found abb. Next match starts at 3
Found ab. Next match starts at 9

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

Предполагается, что все зарегистрированные имена находятся в массиве А:

var A = ;

function lookup(input)
{
  var firstName = /\w+/i.exec(input);
  if (!firstName)
  {
    print(input + " isn't a name!");
    return;
  }

  var count = 0;
  for (var i = 0; i < A.length; i++)
  {
    if (firstName.toLowerCase() == A.toLowerCase())
      count++;
  }
  var midstring = (count == 1) ? " other has " : " others have ";
  print("Thanks, " + count + midstring + "the same name!")
}

Enlight Search Results in Your WordPress Blog

The previous code snippet can be very handy when it comes to displaying search results. If your website is powered by WordPress, here is a more specific snippet that will search and replace a text by the same text within an HTML tag that you can style later, using CSS.

Open your file and find the function. Replace it with the following:

echo $title;

Now, just before the modified line, add this code:

<?php
	$title 	= get_the_title();
	$keys= explode(" ",$s);
	$title 	= preg_replace('/('.implode('|', $keys) .')/iu',
		'<strong class="search-excerpt">\0</strong>',
		$title);
?>

Save the file and open . Append the following line to it:

strong.search-excerpt { background: yellow; }

» Source

«Петя любит Дашу».replace(/Дашу|Машу|Сашу/, «Катю») ¶

Не трудно догадаться, что результатом работы js-выражения выше будет текст . Даже, если Петя неровно дышит к Маше или Саше, то результат всё равно не изменится.

Рассмотрим базовые спец. символы, которые можно использовать в шаблонах:

Символ Описание Пример использования Результат
\ Символ экранирования или начала мета-символа /путь\/к\/папке/ Надёт текст
^ Признак начала строки /^Дом/ Найдёт все строки, которые начинаются на
$ Признак конца строки /родной$/ Найдёт все строки, которые заканчиваются на
. Точка означает любой символ, кроме перевода строки /Петя ..бит Машу/ Найдёт как , так и
| Означает ИЛИ /Вася|Петя/ Найдёт как Васю, так и Петю
? Означает НОЛЬ или ОДИН раз /Вжу?х/ Найдёт и
* Означает НОЛЬ или МНОГО раз /Вжу*х/ Найдёт , , , и т.д.
+ Означает ОДИН или МНОГО раз /Вжу+х/ Найдёт , , и т.д.

Помимо базовых спец. символов есть мета-символы (или мета-последовательности), которые заменяют группы символов:

Символ Описание Пример использования Результат
\w Буква, цифра или _ (подчёркивание) /^\w+$/ Соответствует целому слову без пробелов, например
\W НЕ буква, цифра или _ (подчёркивание) /\W\w+\W/ Найдёт полное слово, которое обрамлено любыми символами, например
\d Любая цифра /^\d+$/ Соответствует целому числу без знака, например
\D Любой символ НЕ цифра /^\D+$/ Соответствует любому выражению, где нет цифр, например
\s Пробел или табуляция (кроме перевода строки) /\s+/ Найдёт последовательность пробелов от одного и до бесконечности
\S Любой символ, кроме пробела или табуляции /\s+\S/ Найдёт последовательность пробелов, после которой есть хотя бы один другой символ
\b Граница слова /\bдом\b/ Найдёт только отдельные слова , но проигнорирует
\B НЕ граница слова /\Bдом\b/ Найдёт только окночние слов, которые заканчиваются на
\R Любой перевод строки (Unix, Mac, Windows) /.*\R/ Найдёт строки, которые заканчиваются переводом строки

Нужно отметить, что спец. символы \w, \W, \b и \B не работают по умолчанию с юникодом (включая кириллицу). Для их правильной работы нужно указывать модификатор . К сожалению, на окончание 2019 года JavaScript не поддерживает регулярные выражения для юникода даже с модификатором, поэтому в js эти мета-символы работают только для латиницы.

Ещё регулярные выражения поддерживают разные виды скобочек:

Выражение Описание Пример использования Результат
(…) Круглые скобки означают под-шаблон, который идёт в результат поиска /(Петя|Вася|Саша) любит Машу/ Найдёт всю строку и запишет воздыхателя Маши в результат поиска под номером 1
(?:…) Круглые скобки с вопросом и двоеточием означают под-шаблон, который НЕ идёт в результат поиска /(?:Петя|Вася|Саша) любит Машу/ Найдёт только полную строку, воздыхатель останется инкогнито
(?P<name>…) Задаёт имя под-шаблона /(?P<воздыхатель>Петя|Вася|Саша) любит Машу/ Найдёт полную строку, а воздыхателя запишет в результат под индексом 1 и ‘воздыхатель’
Квадратные скобки задают ЛЮБОЙ СИМВОЛ из последовательности (включая спец. символы \w, \d, \s и т.д.) /^+$/ Соответствует любому выражению , но не
Если внутри квадратных скобок указать минус, то это считается диапазоном /+/ Аналог /\w/ui для JavaScript
Если минус является первым или последним символом диапазона, то это просто минус /+/ Найдёт любое целое числое с плюсом или минусом (причём не обязательно, чтобы минус или плюс были спереди)
Квадратные скобки с «крышечекой» означают любой символ НЕ входящий в диапазон //i Найдёт любой символ, который не является буквой, числом или пробелом
] Квадратные скобки в квадратных скобках задают класс символов (alnum, alpha, ascii, digit, print, space, punct и другие) /]+/ Найдёт последовательность непечатаемых символов
{n} Фигурные скобки с одним числом задают точное количество символов /\w+н{2}\w+/u Найдёт слово, в котором две буквы н
{n,k} Фигурные скобки с двумя числами задают количество символов от n до k /\w+н{1,2}\w+/u Найдёт слово, в котором есть одна или две буквы н
{n,} Фигурные скобки с одним числом и запятой задают количество символов от n до бесконечности /\w+н{3,}\w+/u Найдёт слово, в котором н встречается от трёх и более раз подряд

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

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

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

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

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

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

Скобки

Скобки ([]) имеют особое значение при использовании в контексте регулярных выражений. Они используются для поиска диапазона символов.

# Значение Описание
Он соответствует любой десятичной цифре от 0 до 9.
Он соответствует любому символу от нижнего регистра a до нижнего регистра z.
Он соответствует любому символу в верхнем регистре A в верхнем регистре Z.
Он соответствует любому символу от нижнего регистра a до верхнего регистра Z.

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

Модификаторы¶

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

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

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

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

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

Квантификатор Описание Шаблон Число соответствий
Соответствует предыдущему элементу ноль или более раз. , ,
Соответствует предыдущему элементу один или более раз. в , в
Соответствует предыдущему элементу ноль или один раз. ,
n Предыдущий элемент повторяется ровно n раз. в , , и в
n Предыдущий элемент повторяется как минимум n раз. , ,
n m Предыдущий элемент повторяется как минимум n раз, но не более чем m раз. , в
Предыдущий элемент не повторяется вообще или повторяется, но как можно меньшее число раз. , ,
Предыдущий элемент повторяется один или несколько раз, но как можно меньшее число раз. в , в
Предыдущий элемент не повторяется или повторяется один раз, но как можно меньшее число раз. ,
n Предыдущий элемент повторяется ровно n раз. в , , и в
n Предыдущий элемент повторяется как минимум n раз (как можно меньше). , ,
n m Предыдущий элемент повторяется не менее n и не более m раз (как можно меньше). , , в

Метасимволы

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

Метасимвол Описание Пример
. Соответствует любому отдельному символу, кроме новой строки /./ соответствует всему, что имеет один символ
^ Соответствует началу или строке/исключает символы /^PH/ соответствует любой строке, начинающейся с PH
$ Соответствует шаблону в конце строки /ru$/ соответствует it-blog.ru и т.д.
* Соответствует любому нулю (0) или более символов /com*/ соответствует computer, communication и т. д.
+ Требуется, чтобы предшествующие символы появлялись хотя бы раз /yah+oo/ соответствует yahoo
\ Используется для экранирования метасимволов /yahoo+\.com/ трактует точку как буквальное значение
Символы внутри скобках // соответствует abc
a-z Соответствует строчным буквам /a-z/ соответствует cool, happy и т.д.
A-Z Соответствует заглавным буквам /A-Z/ соответствует WHAT, HOW, WHY и т.д.
0-9 Соответствует любому числу от 0 до 9 /0-4/ соответствует 0,1,2,3,4

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

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

<?php
$my_email = "name@company.com
	";
if (preg_match("/^+@+\.{2,5}$/", $my_email)) {
echo "$my_email это действительный адрес электронной почты";
}
else
{
  echo "$my_email это не действительный адрес электронной почты";
}
?>

Символы¶

Серия символов соответствует этой серии символов во входной строке.

RegEx Находит

Непечатные символы (escape-коды)

Для представления непечатаемого символа в регулярном выражении используется с шестнадцатеричным кодом. Если код длиннее 2 цифр (более U+00FF), то он обрамляется в фигурные скобки.

RegEx
Находит

символ с 2-значным шестнадцатеричным кодом

символ с 1-4 значным шестнадцатеричным кодом

(обратите внимание на пробел в середине)

Существует ряд предопределенных для непечатных символов, как в языке :

RegEx Находит
tab (HT/TAB), тоже что
символ новой строки (LF), то же что
возврат каретки (CR), тоже что
form feed (FF), то же что
звонок (BEL), тоже что
escape (ESC), то же что

chr(0) по chr(25).
Например соответствует табуляции.
Также поддерживаются буквы в нижнем регистре «a»…»z».

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

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

Adblock
detector