Будь-який символ у регулярних виразах php. Регулярні вирази (шаблони)

) я показав приклад використання регулярних виразів для знаходження певних шматків вихідного коду сторінки. Зараз ми з вами навчимося писати їх самостійно. Ця навичка допоможе писати, очищати текст від непотрібних фрагментів, шукати потрібні частини у великих обсягах тексту тощо.

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

  • preg_replace - пошук і заміна відповідного за регулярним виразом тексту;
  • preg_match - просто пошук з регулювання;
  • preg_split — пошук та розділення тексту.

Принаймні у попередніх уроках ми користувалися саме ними. Вірніше, замість preg_match був preg_match_all, але це по суті те саме, тільки останній не перериває пошук після першого знаходження. Тобто, якщо використовувати preg_match, то ми не знайдемо всі входження, а лише перше.

Вибір якої ситуації функцію використовувати досить простий. Потрібно замінити - використовуємо replace, як у випадку, коли нам потрібно було видалити непотрібні частини коду сторінки, пам'ятаєте?

$page = preg_replace("/ ^]/i", "", $page); $page = preg_replace("/ ^]/i", "", $page); $page = str_replace("",", $page);

Перший параметр функції – регулювання, що визначає Що ми шукаємо. Другий – на що замінюємо. Третій – Де шукаємо. Отже, тут ми брали змінну $page і присвоювали їй результат функції preg_replace де шукали всі input type=checkbox, а також label, що відкриваються і закриваються. Замінювали їх на», тобто просто видаляли. Сподіваюся тут усе ясно. До аналізу самого виразу (першого параметра функції) ми перейдемо трохи пізніше.
Був і приклад використання preg_match_all, який знадобився для пошуку всіх посилань у тексті, що залишився. Посилання нам тоді знадобилися тому, що саме в них були ключові слова, які ми парсили. Ось що було:

Preg_match_all("/ ]+?>(.*?)<\/a>/uis",$page,$ok); for ($j=0; $j ".$ok[$j].""; }

Першим параметром знову ж таки є регулювання, щоб знайти всі посилання, які, природно укладені в тег «a» (якщо не товаришуєте з html розміткою, то почитайте ). Другий — змінна у якій міститься текст, яким відбуватиметься пошук. Третім параметром поставлена ​​змінна, в яку міститься результат $ok. Після цього лише залишається пройтися по всіх потрібних елементах $ok, щоб дістати потрібні нам ключові лови. Окремо слід сказати, що на виході ми отримуємо багатовимірний масив. Саме тому ми виводили його у такий складний спосіб: $ok[$j]. Щоб переглянути структуру масиву, скористайтеся функцією нижче і ви все зрозумієте.

Print_r($ok);

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

Як же писати регулярки

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

Крім цього підтримуються такі метасимволи:

Метасимволи, у свою чергу, можуть мати модифікатори:

Що ж, тепер можемо перейти до розбору наших регулярок із минулого уроку. Спираючись на таблички вище, спробуємо зрозуміти, що ж у нас є. Ось вираз:

/^]/i

Перший та останній сліші «/» показують, що всередині них йде регулярне вираження. При цьому після останнього ми поставили «i», це опція, як у першій таблиці — не враховувати регістр. Усередині слішів сама регулярка. Вона починається зі знака менше і тега input, а також все, що йде потім, до знака точки - простий текст, який потрібно шукати. А ось сама точка і символи після неї — це вже цікавіше. У цьому випадку конструкція «.*?» означає будь-яку послідовність символів. Тобто, якщо поєднати просто текст і цю конструкцію, то ми виберемо весь текст після першого входження і до кінця. Щоб зупинитися потрібно зустріти або тег «більше», що закривається html, або символ початку нового рядка. Ця конструкція якраз нам і дає таку можливість:

Символи в квадратних дужках з'єднані логічним АБО. Кінцем є знак "більше" або початок рядка.
Ось і весь вираз, у ньому ми задали умову початку, середину та умову закінчення. Чи не важко, правда? Ось ілюстрація для більшої наочності:

Давайте розберемо ще одне, щоби все закріпити. Їм ми шукали посилання:

/]+?>(.*?)<\/a>/uis

Читаємо вираз. Знову ж таки, спочатку відкидаємо сліші та опції. Прапори uis зрозумілі, за винятком u, який я не описував - він показує, що ми використовуємо кодування Юнікод. Залишається не так багато. Початком є ​​тег «a», який відкривається, потім іде клас

який позначає НЕ більше або менше (що відкриває та закривається html теги), тобто будь-які символи в даному випадку. До класу додається «+?», які означають, що цей клас буде присутнім 1 або більше разів (але хоча б 1 раз точно). І потім йде html тег для тега «a». Усередині посилання є текст, який задається групою

Адже ми не знаємо, що там буде за текст, тому визначаємо таку групу. І в кінці тег «a», що закривається:

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

Фух. Тема справді досить складна, тут потрібна практика. Можливо я щось роблю не цілком оптимально і можна скласти інші, правильніші регулярні висловлювання, але я такий самий самоучка як і ви, тому не судіть строго, а краще поділіться своїми варіантами в коментарях. Також, якщо щось не зрозуміло – коментарі та сторінка контактів до ваших послуг.

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

Правила складання шаблону (pattern)

Межі шаблону повинні позначатися певними символами, які часто використовують " / ", але я волію використовувати" # " тому, що від великої кількості прямих/зворотних слішів може в очах зарябити, а "грати" зазвичай більше ніде не використовуються. Отже: " #ТутТілоРегулярногоВираження#"

Усередині регулярного виразу використовуються дужки - це вирази, з якими можна проводити маніпуляції, приклад:

#^/catalog/(+)/(+)\.html.*#

Цей вираз призначений для отримання параметрів у рядку URL. На початку рядка йде спецсимвол ^ " - це означає початок рядка. Далі йде " /catalog/" - тут немає спецсимволів, це просто текст, який має утримуватися в рядку. Потім зустріли круглі дужки, тобто дійшли до першого виразу. У квадратних дужках позначаються безліч символів, які можуть бути в рядку в цьому місці. Знак " - " означає перерахування. Знак " \ "Екранує спеціальні символи. Таким чином, у першому виразі у нас можуть йти ВЕЛИКІ і маленькі літери латинського алфавіту, цифри від 0 до 9, знак підкреслення, тире і точка. Тире і точка - це спецсимволи, але тут вони екрановані, тому тут це просто символи. Після квадратних дужок іде знак " + - це означає попередній символ (а у нас це безліч символів задане в квадратних дужках) може йти 1 або більше разів. / " - це просто символ, і аналогічний другий вираз. Потім йде " \.html", що означає текст " .html". А потім спеціалізовані символи " .* "точка означає будь-який символ, а зірочка будь-яку кількість попереднього символу. Тобто після" .htmlможе йти все що завгодно.

Вказівка ​​кількості, квантифікатори

Вище ми вже розглянули такі символи, що вказують на кількість попередніх символів, як + і * . Наведемо всі можливості вказівки кількості:

Спецсимволи

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

"Жадібність"

Розглянемо поняття жадібності регулярного вираження. Наприклад, є рядок:

#()#

Читаємо: вираз:

Начебто все правильно, підвираз підходить під:

Але воно також підходить під:

Його ми і отримаємо, т.к. регулярні вирази за умовчанням "жадібні". Зняти жадібність можна за допомогою модифікатора U", ось так:

#()#U

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

Після регулярного вираження можуть йти модифікатори: " #ТутТілоРегулярногоВираження#ТутМодифікаториВиди модифікаторів:

i Включає режим case-insensitive, тобто. великі та малі літери у виразі не різняться.
m Вказує на те, що текст, за яким ведеться пошук, повинен розглядатися як кілька рядків. За умовчанням механізм регулярних виразів розглядає текст як один рядок незалежно від того, чим він є насправді. Відповідно метасимволи "^" та "$"вказують на початок та кінець всього тексту. Якщо ж цей модифікатор вказано, вони будуть вказувати відповідно на початок і кінець кожного рядка тексту.
s За замовчуванням метасимвол . " не включає в себе символ перекладу рядка. Вказівка ​​цього модифікатора знімає це обмеження.
U Знімає жадібність регулярного вираження
u Включає роботу регулярних виразів з кирилицею в UTF-8, інакше працює не коректно.

php Функції для роботи з регулярними виразами

preg_replace

Пошук та заміна:

Preg_replace (mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]]);

Кожне значення може бути рядком або масивом, якщо $subjectмасив - повертається масив, інакше рядок

preg_split

Розбиває рядок за регулярним виразом:

Preg_split (string $ pattern , string $ subject [, int $ limit = -1 [, int $ flags = 0]]));

Повертає масив, що складається з підрядків заданого рядка subject, яка розбита за межами, що відповідають шаблону pattern.

Почнемо з того, що таке регулярне вираження. Ось дайте відповідь мені на запитання, чи є в слові "test" буква "e"? "Є!" скажете Ви. Тоді я поставлю Вам друге питання, як ви знайшли букву "e" в слові "test"? Відповідь очевидна, беремо перший символ, тобто "t" порівнюємо його з тим, що шукаємо, тобто з "e". Якщо вони не рівні, то беремо другий символ, тобто "e", порівнюємо його з тим, що шукаємо, тобто "e". Вуаль! Знайдено збіг. Відповідь: У слові "test" є буква "e".

А тепер дайте мені відповідь на ще одне питання, де в цьому прикладі регулярне вираження? Сподіваюся Ви здогадалися, що регулярним виразом є те, що ми шукаємо в слові "test". Тобто буква "e" у даному прикладі і є регулярним виразом.

Навіщо використовують регулярні висловлювання в php? У моїй практиці регулярні вирази використовувалися, наприклад, для визначення, чи коректно складено адресу електронної пошти. Також такі висловлювання використовують визначення коректності ім'я користувача і пароля. За допомогою регулярних виразів можна знайти у посиланні адресу та зберегти її. Багато чого можна робити Проаналізувавши це можна виявити головну функцію регулярних виразів і дві побічні. Головна функція, це пошук збігів у рядку. Побічні - це збереження знайдених збігів, і заміна.

Перший регулярний вираз

Теоретично ми розуміємо як знайти символ " e " у слові " test " , як це реалізується практично? Для використання регулярних виразів у php зазвичай використовують функції:

preg_match("регулярний вираз (шаблон)", "змінна в яке здійснюється пошук", "Змінна в яке зберігається результат пошуку (не обов'язковий параметр)"); - Функція пошуку відповідностей
preg_replace("регулярний вираз (шаблон)", "На що замінити знайдений збіг", "змінна в яке проводиться заміна"); - функція заміни

Почнемо використовувати ці функції.. Ось приклад пошуку символу "e" в слові "test":

$a = "test";
if(preg_match("/e/",$a)) echo "знайдено!!";

У коді описано умову, якщо в змінній $a знайдено щось за шаблоном, видати повідомлення "знайдено!!" Як ви могли помітити наш шаблон стоїть між двома "/". У цьому випадку символ "/" символізує початок та кінець нашого шаблону. Сподіваюся, це зрозуміло.

Все це звичайно цікаво ... але ось тільки наш шаблон, який вже дуже простий, не знаходите? Адже рідко нам потрібно знайти якийсь символ у змінній. У більшості випадків нам необхідно знайти багато символів, причому ще й невідомих. Як же бути? Давайте поставимо собі завдання, і спробуємо її вирішити. Припустимо, у нас є рядок, що складається з цифр і однієї невідомої англійської літери.

Як знайти цю літеру? Там може бути будь-яка буква англійського алфавіту, як її визначити? Ви самі відповіли на своє запитання, там будь-яка буква, тобто вона знаходиться в діапазоні від a до z. У регулярних виразах можна використовувати діапазони. Якщо ми не знаємо якийсь символ шукаємо, але точно знаємо, що цей символ є буквою англійського алфавіту, то запис буде наступний:

$a = "123a321";
if(preg_match("//",$a)) echo "знайдено!!";

Зауважте, що діапазон ставиться в "[""]" дужках. Все що укладено в такі дужки визначається як одинсимвол, у разі символ варіюється в діапазоні від a до z. Якщо ж нам знадобиться знайти не букву, а цифру, то запис буде такий:

$a = "abc1cba";
if(preg_match("//",$a)) echo "знайдено!!";

Також хочу зауважити, що регулярні вирази чутливі до регістру, тому символи "A" і "a" абсолютно різні, для пошуку тих і тих символів, пишуть так:

$a = "123a321";
if(preg_match("//",$a)) echo "знайдено!!";

Також існує пошук російських букв, здійснюється так само як і з англійськими:

$a = "123-321";
if(preg_match("/[а-яА-Я]/",$a)) echo "знайдено!!";

Метасимволи

Ми навчилися шукати невідомий символ у рядку. Що ж робити, якщо нам необхідно знайти кілька символів? На допомогу приходять так звані метасимволи... Припустимо, у нас є рядок з циферками, літерами, як його описати в шаблоні? Можна так:

рядок - 123а321
шаблон -

Хм... шаблон дійсно підходить до нашого рядка, і при перевірки на відповідність дасть довгоочікуване true! Але якийсь громіздкий запис, Вам не здається?

Ось як її можна скоротити:

рядок - 123а321
шаблон - *

Мені здається так коротше Що ж являє собою символ "*"? Це і є той самий метасимвол, він означає, що описаний нами символ (а саме символ, який може містити цифри від 0 до 9 або літери англійського алфавіту, від a до z), може повторюватися до нескінченності разів, або ж не одного разу. Так Так! Цей метасимвол знайде збіг у порожній змінній, тому що навіть відсутність описаного нами символу видасть true! Запам'ятайте це

Які ще бувають метасимволи?

Наприклад метасимвол "+" Він майже схожий з метасимволом "*" за одним маленьким винятком. "*" видасть true навіть за відсутності символу, а "+" перевірить наявність хоча б одного символу. Тобто якщо в рядку потрібна наявність мінімумодного символу використовуйте "+" замість "*"

Також часто використовують метасимвол "?" Він означає, що в рядку має бути не більше одного шуканого символу. Давайте я наведу кілька прикладів для двох останніх, описаних мною метасимволів.

Припустимо, нам необхідно перевірити на коректність пароль користувача. Давайте подумаємо що має містити пароль користувача? Ну по-перше він має бути не менше одного символу. По-друге він повинен містити тільки цифри та літери англійського алфавіту, отже регулярний вираз виглядатиме ось так:

$a = "qwerty12345";

Які символи дозволили? Англійські літери будь-якого регістру та цифри. Тепер спробуйте замість пароля залишити порожній рядок.

$a = "";
if(preg_match("/+/",$a)) echo "Пароль вірний";

Вам не з'явиться повідомлення "Пароль вірний". Чому? Тому що метасимвол "+" перевірив рядок на наявність бодай одного символу.

А тепер невеликий фокус, давайте поглянемо на наш вираз, адже ми не дозволяли в ньому, ну скажемо прогалину, адже так? поставте пробіл в кінці пароля і запустіть

$a = "qwerty12345";
if(preg_match("/+/",$a)) echo "Пароль вірний";

І чому ми бачимо наше повідомлення про коректний пароль? Все досить просто... Функція preg_match(); зупиняє свою перевірку за першого ж збігу. Тобто символ "q" підходить під описаний нами шаблон, а все інше для функції вже не важливо. Що ж робити? Ось як це виправити:

$a = "qwerty12345";
if(preg_match("/^+$/",$a)) echo "Пароль вірний";

Додаючи "^" на початку виразу і "$" наприкінці, ми говоримо функції, що шаблон повинен відповідати всярядок. Якщо ви запустите цей код, то повідомлення не побачите, тому що в кінці пароля стоїть неприпустимий символ - пробіл

Тепер змініть метасимвол "+" на метасимвол "?". Як Ви думаєте, що станеться? Правильно повідомлення про коректність пароля буде відсутнє, тому що в паролі більше одного символу. Сподіваюся я нормально пояснив роботу, цих трьох, часто використовуваних, метасимволів

Іноді "не" краще

Ми, як мінімум, навчилися перевіряти правильність пароля, і це добре! Давайте я Вам розповім про ще один спосіб пошуку чогось у рядку. Ось скажемо нам потрібно перевірити відсутність у рядку цифр. Як це зробити? Ось рядок:

(Я спеціально ввів у неї ці "-_+()" символи, щоб життя медом не здавалося...) Ми могли б скласти наступний вираз:

Але погодьтеся, адже ми не завжди знаємо які символи використовуються в рядку, але нам точно відомо, що цифр у ньому не повинно бути! Отже, логічніше було б просто написати шаблон, який пропускав би рядки в яких ніцифр, а не ті, в яких є "О боже мій скільки ж не зрозумілих символів!". Ось приклад правильно складеного виразу для таких завдань:

$a = "a-_+()";
if(preg_match("/^[^0-9]+$/",$a)) echo "Цифр немає!";

Як же ми цього досягли? Ми ввели символ , але!поставлена ​​на початку кришка "^" ([^0-9]) говорить про те, що в рядку цього символу бути не повинноСподіваюся з цим розібралися

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

Побачив, зберіг!

Мій блог

$a = " Мій блог";
preg_match("/ /", $a);

У нашому регулярному виразі ми описали всі можливі символи, які можуть входити в посилання. Так само хочу звернути увагу на символи лапки і "/" у нашому виразі. Перед ними стоїть зворотний сліш, для чого він? Справа в тому, що "/" і лапка самі по собі спецсимволи. І для того, щоб шаблон їх сприйняв як звичайні символи, нам необхідно їх екранізувати. Екранізація проводиться шляхом додавання перед спецсимволами зворотного слішу. Сподіваюся зрозуміло

$a = " Мій блог";
preg_match("/ /", $a, $b);

Ну і відповідно необхідно дописати додатковий параметр у вигляді змінної $b, в ній і зберігатиметься знайдене посилання. Також необхідно знати, що результат пошуку міститься в масив. Отже змінна $b - масив. Шукана нами інформація знаходиться під індексом 1. А це означає, що результат пошуку в змінній $b. виведемо результат на екран:

$a = " Мій блог";
preg_match("/ /", $a, $b);
echo $b;

Правильна адреса, запорука успіху!

Ну і на кінець, відповідь на запитання, чи коректний e-mail? Для початку необхідно дізнатися, які символи дозволені в адресах? Наскільки мені відомо, у дозволені символи входять:

  • англійські літери, цифри, "_", "-" емммм начебто все... Виходитимемо їх цього.
  • Далі у нас йде "@"
  • Після, англійські літери
  • Далі, точка
  • І знову англійські букви...

Отже регулярний вираз буде наступним:

$a = " [email protected]";
if(preg_match("/^+@+.+$/", $a)) echo "електронна адреса складена коректно!";
else echo "e-mail адреса складена НЕ коректно!";

Ну, що ж... Буду сподіватися, що такі записи тепер не лякають Вас, і Ви в них цілком можете розібратися.

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

Що стосується циклу статей про розробку cms блогу, першу частину циклу оголошую закритою!Незабаром ми почнемо реалізовувати адмін панель, так що не "перемикайтеся" Якщо у Вас є якісь питання, із задоволенням відповім. Усього Вам найкращого, у мене все!