Регулярні вирази PHP8. Приклади - розшифровка регулярки
Регулярні вирази в PHP8 дають нам змогу вибрати по певній масці необхідні дані. ЩО доволяє легко сортувати, робити фільтр та здійснювати пошук по масці або регулярному виразу.
Приклади регулярок на практиці
Синтаксис шаблонів.
Ми можемо згрупувати символи всередині шаблону наступним чином:
- Звичайні символи, які слідують один за другим, наприклад,
hello
- Індикатори початку і закінчення рядка у вигляді
^
і$
- Індикатори підрахунку, такі як
+
,*
,?
- Логічні оператори, такі як
|
- Групуючі оператори, такі як
{}
,()
,[]
//В нас є строка
"E:/OpenServer/0-upload/img/img-3885.webp"
$src = preg_replace("/(\/0-upload\/)/", '$1 . 222222', $src);
//..результат var_dump($src); :
/0-upload/ . 222222img/img-3885.webp
//Якщо потрібно в регулярку підставити значення змінної ($g_renm):
//Спочатку в регулярку вставляємо (%s):
$srcrr = preg_replace("/(.*)(\/0-upload\/img\/\d{4}\/\d{1,2}\/)(.*)(\.webp)/", "$1$2%s$4", $src);
//міняємо (%s) на свою змінну
$srcrr = sprintf($srcrr, $g_renm);
() - В дужках те що шукаємо
$1 - вставляє те що у перших дужках
Пояснення до знаків регулярних виразів:
Регулярний вираз (шаблон) | Проходить перевірку (об’єкт) | Не проходить перевірку (об’єкт) | Коментар |
(.{0,16}) | Будь які символи від 0 до 16 | ||
world |
Hello world | Hello Ivan | Проходить, якщо шаблон присутній деінде в об’єкті |
^world |
world class | Hello world | Проходить, якщо шаблон присутній на початку об’єкта |
world$ |
Hello world | world class | Проходить, якщо шаблон присутній в кінці об’єкта |
world/i |
This WoRLd | Hello Ivan | Виконує пошук в нечутливому до регістру режимі |
^world$ |
world | Hello world | Рядок містить лише “world” |
world* |
worl, world, worlddd | wor | Присутньо 0 або більше “d” після “worl” |
world+ |
world, worlddd | worl | Присутня принаймні одна “d” після “worl” |
world? |
worl, world, worly | wor, wory | Присутньо 0 або 1 “d” після “worl” |
world{1} |
world | worly | Присутня одна “d” після “worl” |
world{1,} |
world, worlddd | worly | Присутня одна або більше “d” після “worl” |
world{2,3} |
worldd, worlddd | world | Присутньо 2 або 3 “d” після “worl” |
wo(rld)* |
wo, world, worldold | wa | Присутньо 0 або більше “rld” після “wo” |
earth|world |
earth, world | sun | Рядок містить «earth» або “world” |
w.rld |
world, wwrld | wrld | Містить будь-який символ замість крапки |
^.{5}$ |
world, earth | sun | Рядок містить рівно 5 символів |
[abc] |
abc, bbaccc | sun | У рядку є “a”, або “b”, або “c” |
[a-z] |
world | WORLD | У рядку є будь-які малі літери |
[a-zA-Z] |
world, WORLD, Worl12 | 123 | У рядку є будь-які малі або прописні букви |
[^wW] |
earth | w, W | Фактичний символ не може бути “w” або “W” |
При використанні екранування зворотним слешем деякі символи виконують спеціальну інтерпретацію:
\d - будь-яка десяткова цифра ([0-9]);
\D - будь-який символ, крім десяткової цифри;
\s - будь-який пробільний символ ([\r\n\t\f]);
\S - будь-який непробільний символ;
\w - будь-який символ, що утворює "слово" ([a-zA-Z0-9_]);
\W - будь-який символ, що не утворює "слово";
\t - символ табуляції;
\n - символ переводу рядка;
\\ - символ зворотного слешу (\);
\. - Символ крапки (.).
Символ крапки "." позначає будь-який символ у регулярному виразі крім символів розриву рядка "\r" або "\n", тому для пошуку крапки слід екранувати цей символ.
(.*?) - Символ ?, що стоїть у регулярному вираженні після іншого квантифікатора, переводить його в лінивий режим
Таблица 13.1. Метасимволы, распознаваемые ВНУТРИ квадратных скобок |
|
Метасимвол |
Значение |
\ |
Переходный символ со множеством назначений |
^ |
Отрицание класса, но только если это первый символ (например, «^\d» задает все, кроме цифр) |
- |
Задает диапазон символов (например, «0-9» задает все цифры, «A-Z» – все латинские буквы) |
] |
Вычисляет символьный класс |
--
Таблица 13.2. Метасимволы, распознаваемые ВНЕ квадратных скобок |
|
Метасимвол |
Значение |
\ |
Переходный символ со множеством назначений |
^ |
Объявляет начало объекта (или строки в многострочном режиме). То есть этот символ определяет, что искомый текст должен находиться в начале строки. Альтернатива: «\A» |
$ |
Объявляет конец объекта (или строки в многострочном режиме). То есть этот символ определяет, что искомый текст должен находиться в конце строки. Альтернативы: «\Z», «\z» |
. |
Совпадает с любым символом, кроме символа перевода строки (по умолчанию) |
[ |
Начинает определение символьного класса |
] |
Заканчивает определение символьного класса |
| |
Разделяет перечисление альтернативных вариантов |
( |
Начинает подшаблон регулярное (подвыражение) |
) |
Заканчивает подшаблон |
? |
Расширяет значение «(», квантификаторов 0 или 1, и квантификатор минимизации |
* |
0 или больше повторений (квантификатор) |
+ |
1 или больше повторений (квантификатор) |
{ |
Начинает минимальный/максимальный квантификатор |
} |
Заканчивает минимальный/максимальный квантификатор |
Як формується PHP регулярний вираз?
Зразки регулярних виразів у PHP8:
// Перелік розширень
preg_match("/.tpl|.php|.css|.htm|.js/ui", $file);
// Усі латинські літера та усі цифри, тире, крапка, підкреслення з умовою від 2 до 22 знаків
preg_match("/^[a-z0-9-._]{2,22}$/ui", $grdel_file)
Приклад регулярки, ДЛЯ ЗРАЗКА - перевірка емейлу :
//ім`я має містити букви і можливо цифри довжиною від 5 до 25 символів.
//i - вкінці після слешу означає нечутливість до регістру
<?php
$pattern = '/^[a-zA-Z0-9_.-]{5,25}$/i';
$username = "rullan_user-23";
if (preg_match($pattern, $username)) {
echo "Перевірка пройдена успішно!";
} else {
echo "Перевірка не пройдена!";
}
?>
//перевіряємо правильність введення емейлу:
<?php
$pattern = "/^[a-z0-9_\-\.]+@[a-z0-9_^\.]+\.[a-z]{1,6}$/ui";
$email = "some-email@test.com";
if (preg_match($pattern, $email)) {
echo "Перевірка пройдена успішно!";
} else {
echo "Перевірка не пройдена!";
}
?>
Пояснення до перевірки емейлу:
^[a-z0-9_\-\.]+ - До символу собачки шаблон шукає букви та цифри, знак тире, нижнього підкреслення та крапки одне або більше число входжень починаючи з початку рядк
@[a-z0-9_^\.]+ - починаючи з собачки, маючи той же набір символів, що і перша частина:
\.[a-z]{1,6}$ - перевіряємо доменну зону, яка складається виключно з рядка букв певної кількості символів до кінця рядка
модифікатор "i" здійснюватиме пошук за регулярним виразом без урахування регістру.
модифікатор "u" необхідно додавати для правильної обробки українських символів у кодуванні UTF8 (PCRE_UTF8).
Функції для регулярних виразів:
- Функція Preg_match дійснює пошук у рядку за регулярним виразом
- Функція Preg_match_all шукає усі збіги
- Функція Preg_replace крім пошуку, здійснює і заміну за регулярним виразом
- Функція Preg_split розбиває рядок за регулярним виразом.
Модифікатори регулярок - остання літера після "/" (REGEX FLAGS):
- (g) global - Не повертатись після першого матчу
- (m) multi line - парсить багато строк а не одну
- (i) insensitive - Збіг без урахування регістру
- (x) extended - дозволяє використовувати пробіли та коментарі-#
- (s) single line - Крапка відповідає новому рядку
- (u) unicode - Збіг з повним юнікодом
- (U) Ungreedy - Зробіть квантифікатори лінивими
- (A) Anchored - Прив'язка до початку шаблону або до кінця останнього збігу
- (J) Jchanged - Дозволити імена підшаблонів, що повторюються.
- (D) Dollar end only - $ відповідає тільки кінцю шаблону
Квантифікатори або скільки разів має повторитись:
- p+ Відповідає одному або декільком входженням літери p.
- p* Відповідає нулю чи більше входжень літери p.
- p? Відповідає нулю або одній появі літери p.
- p{2} Відповідає рівно двом входженням літери p.
- p{2,3} відповідає як мінімум двом, але не більше трьох появ літери p.
- p{2,} Відповідає двом або більше входженням літери p.
- p{,3} Відповідає лише трьом появам букви p
$pattern = "/[\s,]+/";
$text = "My favourite colors are red, green and blue";
$parts = preg_split($pattern, $text);
Маски в регулярках:
Маска задається круглими скобками - (), а дістається значення через $1 або $matches[1]:
//ВАРАНТ №1
$content = '⮘page-title⮚';
$oldtgrpl = '/([⮘])+([a-zA-Z0-9]+)+((?:-){1})([a-zA-Z0-9]+)+[⮚]/ui';
$content = preg_replace($oldtgrpl, "$2-$4", $content);
print_r($content);
//РЕЗУЛЬТАТ:
page-title
//ВАРАНТ №2
$pattern = '/Міняємо автора поста ([0-9]+) з "(.+)" на "(.+)"./';
$str = 'Міняємо автора поста 123 з "Олекса" на "Богдан".';
preg_match($pattern, $str, $matches);
$articleId = $matches[1];
$oldAuthor = $matches[2];
$newAuthor = $matches[3];
var_dump($articleId,$oldAuthor,$newAuthor);
//Вивиде на екран:
:26:string '123' (length=3)
:26:string 'Олекса' (length=8)
:26:string 'Богдан' (length=8)
У жадібному режимі (за замовчуванням) квантифікатор повторюється стільки разів, скільки це можливо.
Двигун регулярного виразу намагається отримати максимальну кількість символів, що відповідають .+, а потім скорочує цю кількість символ за символом, якщо залишок шаблону не збігається.
Лінивий режим
«Лінивий» режим протилежний «жадібному». Він означає: "повторювати квантифікатор найменшу кількість разів".
Ми можемо включити його, вставивши запитання '?' після квантифікатора, тобто буде *? або +? або навіть ?? для '?'.
Прояснимо: зазвичай знак питання? сам по собі є квантифікатором (нуль або один), але якщо він доданий після іншого квантифікатора (або навіть після самого себе), він отримує інше значення - він змінює режим збігу з жадібного на лінивий.
=====
Сервіс для створення регулярок - https://regex101.com/