PHP робота з регулярними виразами

Що таке регулярні вирази

В основному роботу регулярних виразів можна описати приблизно наступним шляхом, регулярне вираження це метод зіставлення із зразком або узгоджувальних моделей у рядку. У PHP найчастіше використовується PCRE або “Perl Compatible Regular Expressions”. Сьогодні ми залишимо прості методи пошуку рядків і працюватимемо з сильнішим інструментом, яким багато хто користується але не знає як він працює. Тут ми спробуємо декодувати безглузді ієрогліфи, якими їх усі вважають і зробимо це на прикладах.. Найголовніша помилка ті хто вивчає регулярні вирази це спроба зрозуміти все в один раз..

Починаємо вивчення

Створіть у себе на тестовому сервері файл index.php та розмістіть у нього код:

Дещо модифікуємо код і допишемо функцію preg_match().

Після запуску скрипту ми отримаємо 1, а це означає, що частина тексту була знайдена в рядку $string (PHP 1 та TRUE рівні відповіді).

Ми прищепили приклад того, як знайти рядок, але є спосіб зробити це швидше через стандартні функції php StrPos () і strstr ().

Вказівка ​​початку рядка в регулярному виразі

Для вказівки початку рядка у виразі необхідно додати піктограму ^, давайте будемо менше говорити і спробуємо практично змінити наш код до наступного виду:

Після виконання коду ви побачите напис “Цей рядок починається з abc”, тому що наш рядок дійсно починається з букв “abc”. символ (^) дає нам пошук тільки на початку рядка, але не по всій. Ця конструкція за замовчуванням враховує регістр.

Пошук підрядки на початку без урахування регістру

Раніше ми використали комбінацію if(preg_match(“/^ABC/”, $рядок)), але ця комбінація видала б помилковий результат, оскільки вона враховує регістр літер. Розглянемо PHP код, який не враховуватиме регістр літер при пошуку.

Конструкція трохи змінилася і був доданий ще один модифікатор i preg_match(“/^ABC/i«, $рядок) – нечутливий до регістру (реєстронезалежний). Після наших поправок скрипт відмінно знаходитиме підрядок.

Як знайти рядок по її кінцівці

Багато в чому пошук рядка на її кінцівці схожий на попередній приклад. Все що необхідно додати z до кінця шаблону пошуку.

Оскільки наш рядок закінчується на 89 і шаблон пошуку відповідає кінцю рядка, то результат буде “Кінець рядка дорівнює 89”.

Мета символ

Ми з вами вже використовували спеціальні символи, такі як (^) і ($) ці символи, поряд з іншими називають мета символами. Ось список мета символів які також використовуються в регулярних виразах:

. (Повна зупинка)
^ (Карат) - Початок рядка
* (Астерікс) – означає будь-яку кількість символів у рядку, попередніх "зірочці", у тому числі і нульова кількість символів.
+ (Плюс) - Вказує на те, що попередній символ або вираз зустрічається 1 або більше разів. Відіграє ту ж роль, що й символ “зірочка” (*), за винятком випадку нульової кількості входжень.
? (Знак питання) – означає, що попередній символ або регулярний вираз зустрічається 0 або 1 раз. В основному використовується для пошуку одиночних символів.
{ (Відкриття фігурної дужки)
} (Закриваюча фігурна дужка) – {a,b} - кількість входжень попереднього символу або підмаски від a до b. Якби не вказано, вважається, що верхнього кордону немає. Наприклад, * - теж саме, що {0,}. ? – те саме, що {0,1}. {5,7}5,6 або 7 повторень.
[ (Розкриваюча дужка)
] (Закриваюча дужка) – призначені для завдання підмножини символів. Квадратні дужки, всередині регулярного виразу, вважаються одним символом, який може приймати значення, перелічені всередині цих дужок.
\ (Зворотна коса риска) – служить для екранування спеціальних символів, це означає, що екрановані символи повинні інтерпретуватися буквально, тобто. не як мета символи, а як прості символи.
| (Труба) - Виконує роль логічного оператора “АБО” у регулярних виразах та служить для завдання набору альтернатив повторно(a|д)d’.
( (Відкриваючі дужки)
) (Закриваючі дужки) – призначені виділення груп регулярних выражений. Вони корисні при використанні з оператором “|” та при вилученні підрядка за допомогою команди вираз.

Ми розглянемо кожен із мета символів на прикладах під час цього уроку, але важливо, Щоб ви знали, які вони є. Якщо ви хочете знайти рядок, що містить один із цих символів, наприклад: «1 + 1«, то вам потрібно, щоб програма вважала їх звичайними символами, а не мета символами, для цього додамо зворотну косу межу та заекрануємо символ:

У цьому прикладі \ заекранував плюс і вираз використовував його як звичайний символ, в іншому випадку вираз спрацював би як хибне.

Розглянемо, що можуть робити інші мета символи

Ми вже бачили символ каретки^ і долар $? давайте подивимося на інші, починаючи з квадратних дужок []. Квадраті дужки призначені для пошуку символів [abcdef] або діапазон символів [а-ф]. Подивимося на приклад регулярного виразу:

Вираз поверне істину, якщо в рядку зустрічаються слова big, болото, помилка, мішок, але не просити.

Ще можна використати ось таку комбінацію [abcdef$], в даному випадку знак $ буде всього лише доларом, але не мета символом. Практично всі цілі символи не мають значення, за винятком деяких випадків.

Давайте спробуємо наступний скрипт:

Результатом роботи скрипту буде висновок 0 -> a скрипт виводить символи до символу b.

Спробуємо трохи модифікувати наш скрипт і використовувати функцію preg_match_all().

Як ви можете бачити з результатів наведеного вище сценарію, він друкує всі символи рядка, які не відповідають шаблону “B”
acefghijklmnopqrstuvwxyz0123456789.
Зробимо ще один крок вперед для того, щоб відфільтрувати всі цифри з рядка:

Цей скрипт повертає рядок:
abcefghijklmnopqrstuvwxyz

Виходячи з вище зазначеного коду ми можемо бачити, що знак ^ у наведених вище прикладах означає заперечення (Усі крім перелічених символів).

Залишайтеся з нами, далі ще цікавіше

Спробуємо використовувати екранування мета символів, щоб використовувати їх у пошуку. Найпростіше буде зрозуміти на основі результату, на прикладі:

Результатом роботи скрипту буде:

[]

Це тому що ми вказали що хочемо взяти всі символи що відповідають []. Для того щоб вираз спрацював правильно, ми використовували косі риси., якщо вам треба, щоб коса риса розцінювалася як простий символ, вам буде необхідно вказати дві косі риси \\, наприклад для такого виразу c:\dirfile.php.

Розглянемо роботу з оператором крапкою ( . ) на простому прикладі:

В результаті ми отримаємо 1, тому що в нашому рядку є слово sex, цей вислів також знаходитиме слова SOX, SUX і SX, але не знаходитиме Stix.

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

Код вище поверне це:
секс
в
полудень
податки
4

Спочатку ми вивели рядок, а оператор виставив переноси. Нижче ми бачимо число 4, це кількість слів яке знайшла функція preg_match_all ().

Давайте далі ми попрацюємо з мета символом ( * ). Цьому оператору буде відповідати будь-яка кількість будь-яких символів., які можуть бути до оператора, а можуть і не існувати. Подивимося на приклад нижче:

В результаті ми отримаємо 1 оскільки ми знайшли 1 вираз, який відповідає виразу. Також вірним буде вираз pp (без символів) і phhhp (з кількома символами).

Якщо нам потрібно виключити порожній результат виду pp, то можна використовувати мета символ ( + ). Подивимося на прикладі:

Використання символу ( + ) працює схоже на ( * ), але плюс не враховує пусте значення.

Наш наступний мета символ питання питання ( ? ), він означає, що попередній символ може бути, а може й не бути. Прикладом може бути написання телефонного номера, обидва висловлювання будуть істиною (1234-5678) і (12345678).

Аналогічний результат буде при використанні наступного коду:

Далі у нас є фігурні дужки або {} метасимвол. Задають кількість входжень попереднього виразу чи діапазону. Фігурні дужки обов'язково повинні екрануватися косою межею “[0-9]\{5\}».
Вираз “[0-9]\{5\}» – відповідає підрядку з п'яти десяткових цифр (символів з діапазону від 0 до 9, включно).

Далі ми будемо використовувати вираз у якому після тексту “PHP” обов'язково маємо доповнитися рівно 3 цифрами.

Результатом регулярного вираження буде істина (1). З регулярного виразу видно що воно має починатися текстом PHP і доповнюватись трьома цифрами від 0 до 9.

Спеціальні послідовності

Зворотна коса риса також використовується для спеціальних послідовностей. Давайте розберемося які бувають послідовності?

  • \d – виражає будь-які цифрові символи подібно до виразу [0-9]
  • \D – відповідає будь-яким цифровим символам подібно [^0-9]
  • \s – відповідає будь-яким символам виду [ \тнрфв]
  • \S – відповідає будь-якому символу виду [^ tnrfv]
  • \w – відповідає будь-яким алфавітно цифровим символам та символу нижнього підкреслення подібно [a-zA-Z0-9_]
  • \W – відповідає будь-яким алфавітно цифровим символам та символу нижнього підкреслення подібно [^a-zA-Z0-9_]

Ці послідовності можна використовувати для скорочення ваших регулярних виразів. Наступний приклад показує, як можна очистити рядок від зайвих символів..

Такий вираз буде корисним, якщо вам потрібно почистити логін користувача, від зайвих та неприпустимих символів.

Також при чищенні рядка часто необхідно переконатися, що рядок не починається з цифр, це можна зробити за допомогою наступного прикладу:

Цей приклад покаже, що в рядку спочатку будує цифра 2.

Давайте скористаємося точкою щоб визначити чи є в рядку хоча б один символ.

точка ( . ) означає будь-якого символу, не менше одного, за винятком символу перекладу рядка (\п).

Спробуємо використовувати послідовність для отримання кількості слів у рядку розділеного n.

Результат виразу:

секс
в
полудень
податки
4

Підсумуємо наші знання

Почнемо поєднувати наші висловлювання у складніший вигляд. Наступний вираз показує, що в рядку має бути одне зі слів This або That або There.

Ще один цікавий приклад скрипту для визначення початку слова.

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

Якщо ви все зробили правильно, то результатом виразу буде:

0->Привіт
1->Він

$сірники[0] містить повний текст шаблону виразу – Hello.
$сірники[1] містить першу частину шаблону виразу.

Модифікатори та затвердження

Як ми бачили раніше в цьому уроці, ми змогли створити регулярний вираз, яке було чутливе до регістру з використанням /i . Це модифікатор і є одним із багатьох використовуваних у регулярних виразах для виконання змін у поведінці зіставлення зі зразком. Ось список з модифікаторів та тверджень регулярних виразів, використовуються в PHP.

Модифікатори

i – реєстронезалежність.
U – інвертує жадібність. це означає, що шаблон збігається з найбільшою можливою кількістю символів, які під цей шаблон.
s – якщо використовується, то символ . відповідає і перекладу рядка n. Інакше вона йому не відповідає.
m – мультирядок (Кілька рядків)
x – змушує ігнорувати усі неекрановані пробільні символи, якщо вони не перераховані у символьному класі. Комфортно, коли ентерами і пробілами ви хочете навести зручно читання в регулярні.
e – Якщо використовується цей модифікатор, preg_replace() після виконання стандартних підстановок в рядку, що замінюється, інтерпретує її як PHP-код і використовує результат для заміни шуканого рядка. Одинарні та подвійні лапки, зворотні слеші (\) NULL-символи будуть проекрановані зворотними слешами в зворотних посиланнях, що підставляються.. (Працює лише з preg_replace).
S – у разі, якщо планується багаторазово використовувати шаблон, має сенс витратити трохи більше часу на його аналіз, щоб зменшити час його виконання. В разі, якщо цей модифікатор використовується, проводиться додатковий аналіз шаблону. На даний момент це має сенс тільки для “незаякорених” шаблонів., не починаються з певного символу. Про це трохи пізніше.

Твердження

б – межа слів (межа слова)
Кордон слова створюється між двох "b" модифікаторів.
Це спеціальний “підпираючий тип модифікаторів, які дозволяють вказати ТОЧНИЙ Збіг.
Текст повинен збігтися тільки з точним шаблоном, укладеним у “b”
Наприклад, шаблон "кішка" не відповідає "каталогу".
Б – Без межі слів (не є межею слова)
Цей модифікатор відноситься до попереднього, але B не ставить умови гранця слова, а навпаки заперечує межу слів. Цей модифікатор корисний, коли потрібно знайти щось усередині тексту, який знаходиться всередині слова, але не на самому початку чи наприкінці фрази.
A – PCRE_ANCHORED
Якщо використовується цей модифікатор, відповідність шаблону досягатиметься лише в тому випадку, якщо він "заякорений", тобто. відповідає початку рядка, в якій проводиться пошук. Того ж ефекту можна досягти відповідною конструкцією з вкладеним шаблоном, яка є єдиним способом реалізації цієї поведінки у Perl.
Z – вказівка ​​кінця рядка.
кінець даних або позиція перед останнім перекладом рядка (незалежно від багаторядкового режиму).
z – вказівка ​​кінця рядка.
кінець даних (незалежно від багаторядкового режиму).
G – перша позиція, що збігається в рядку.

Попрацюємо з модифікаторами та твердженнями на прикладах

Як ви можете бачити з наведеного вище списку, є багато способів, щоб змінити поведінку регулярних виразів, давайте спробуємо попрацювати з модифікаторами та твердженнями по черзі на простих прикладах.

Модифікатор (i)

Якщо ви читали попередні частини цього уроку не буде ніякого подиву, що дана конструкція вважала схожими "ABC" і з abc, тому що ми використовували модифікатор реєстронезалежності (i) .

Модифікатор (с)

Продовжимо вивчення та розглянемо модифікатор (с). Якщо використовується цей модифікатор, то символ ( . ) відповідає і перекладу рядка n. Інакше вона йому не відповідає. Спершу ми спробуємо приклад без модифікатора (с).

Як бачимо цей приклад повернув відповідь ( 0 ), для того, щоб результат був позитивний ( 1 ), а символ ( . ) враховував n, необхідно додати у вираз модифікатор ( с )? перебудуємо наш приклад.

Наведений вище код відображатиме число 1, оскільки рядок за шаблоном виразу було знайдено.

Модифікатор (м)

При додаванні модифікатора до рядка, відбуватиметься цікава магія. Регулярний вираз сприйматиме один рядок як кілька, якщо в ній стоїть перенесення n. Для того, щоб було простіше зрозуміти дію модифікатора, подивіться на приклад.

У цьому прикладі ми за допомогою мета символу ( ^ ) шукаємо слово noon на початку рядка. Наш рядок починається зі слова sex, а значить у звичайному випадку ми б не знайшли шукане слово. Так як у нашому прикладі всі слова розділені n і стоїть модифікатор ( м ), то кожне слово сприйматиметься як початок рядка. Щоб при пошуку не враховувався регістр літер, ми ще додали модифікатор ( i ). Якщо уважно подивіться на приклад вище, то побачите що можна використовувати кілька модифікаторів поряд.

Модифікатор ( x ) робить наш вираз довшим, але він дозволяє ділити регулярний вираз на кілька рядків і дає можливість прокоментувати кожну дію у виразі., коментарі в регулярних висловлюваннях роблять їх зрозумілішими. Далі описувати немає сенсу, просто подивіться як буде працювати такий регулярний вираз, воно працює як і попереднє але має коментарі та моїфікатори ( imx ).

Наступний наш модифікатор це ( С ), за допомогою нього можна зробити аналіз рядка до порівняння з шаблоном. Вираз може спростити виконання шаблону у випадку множинного входження.

Розглянемо приклад множинного входження (збіги):

Модифікатор ( С ) використовують рідко, але раптом він вам зустрітися ви знатимете для чого він потрібен, або знати де можна почитати про цього модифікатора.

Далі ми попрацюємо з межами слів., цей модифікатор дозволяє нам чітко визначити де починається та закінчується слово. Часта помилка програмістів у використанні цього модифікатора для пошуку входження. Пошук входження з b поверне результат false. Розглянемо з прикладу:

Шукане слово lab не було знайдено у слові available через використання b у шаблоні. Для модифікатора b у пошуку, слова cat та catalog будуть різними словами.

Розглянемо ще один приклад пошуку виразу:

Пошук вдався!

Модифікатор B

Цей модифікатор (\Б) заперечує межу слова. Модифікатор буде корисним у випадку коли необхідно знайти що-небудь усередині тексту, за шаблоном, який знаходиться всередині слова, але не на самому початку чи наприкінці фрази.

Приклад зі словом, яке починається заданим входженням

На прикладі вам має бути зрозуміло, чому слово “the” не було знайдено, все тому, що ми за допомогою регулярного виразу “/Btheb/” вказали що “the” це кінець слова, але не ціле слово.

Модифікатор U використовується для інвертування жадібності.

Цей модифікатор інвертує жадібність квантіфікаторів, таким чином вони за замовчуванням не жадібні. Але стають жадібними, якщо за ними слідує символ ?. Його також можна встановити за допомогою (?U) налаштування модифікатора всередині шаблону або додавши знак питання після квантифікатора (наприклад, .*?).

Приклад використання жадібних і лінивих виразів з wikipedia

Вираз (<.*>) відповідає рядку, містить кілька тегів HTML-розмітки, повністю.
<стор><b>wp-admin.com.ua</b> — уроки розробки сайтів та <i>cms wordpress</i> </стор>
Щоб виділити окремі теги, можна застосувати ліниву версію цього виразу: (<.*?>) Їй відповідає не весь показаний вище рядок, а окремі теги (виділені кольором):
<стор><b>wp-admin.com.ua</b> — уроки розробки сайтів та <i>cms wordpress</i></стор>

Використання preg_replace

Думаю тут простіше буде спробувати ввести поданий код і подивитися на результат роботи функції.

Багато розробників можуть дорікнути що робота з функцією str_replace() проходить набагато швидше, але ми зараз лише навели простий приклад, далі буде цікавіше.

Розглянемо складніший приклад заміни за допомогою функції preg_replace().

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

https://www.php.su/lessons/?lesson_17

https://www.skillz.ru/dev/php/article-Regulyarnye_vyrazheniya_dlya_chaynikov.html

https://www.phpro.org/tutorials/Introduction-to-PHP-Regex.html

https://www.compileonline.com/execute_php_online.php

Ніколаєнко Максим

Директор веб-студии ProGrafika. Займаюсь розробкою, дизайном та просуванням веб-сайтів. Завжди радий новим читачам блогу та добрим клієнтам.


Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *

Цей сайт використовує Akismet для зменшення спаму. Дізнайтеся, як обробляються ваші дані коментарів.

Шаблони для WordPress
Найкращий хостинг в Україні
Стабільний хостинг для Drupal