PHP 5 about PHP 5 старт PHP 5 установка PHP 5 синтаксис PHP 5 змінні PHP 5 echo і print PHP 5 типи даних PHP 5 strings PHP 5 константи PHP 5 оператори PHP 5 if...else...elseif PHP 5 switch PHP 5 цикл while PHP 5 for і foreach PHP 5 функції PHP 5 масиви PHP 5 сортування масивів PHP 5 superglobals PHP 5 форми input PHP 5 форми обробка PHP 5 форми - обов'язкові поля PHP 5 форми - перевірка електронної пошти і URL РНР 5 форми заповнення PHP 5 багатовимірні масиви PHP 5 час і дата PHP 5 include PHP 5 файли обробка PHP 5 файли Open/Read/Close PHP 5 файли створення / запис PHP 5 файли завантаження PHP MySQL бази даних PHP MySQL Підключення PHP MySQL Створення бази даних PHP MySQL Створення таблиці PHP MySQL вставка даних PHP MySQL Отримання ідентифікатора останнього доданого запису PHP MySQL вставка кількох записів PHP MySQL Підготовлені вирази PHP MySQL відображення даних з таблиці PHP MySQL Видалення даних PHP MySQL оновлення даних PHP MySQL обмежити вибірку даних PHP регулярні вирази 1 PHP регулярні вирази 2 PHP регулярні вирази 3 PHP регулярні вирази 4 PHP ООП PHP ООП class PHP ООП модифікатори доступу PHP ООП extends PHP ООП статичні методи і властивості, константи PHP ООП abstract PHP ООП interface PHP альтернативний синтаксис керуючих конструкцій

PHP регулярні вирази 1


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

У народі: регекспи, регулярки.

По-простому - це вирази для пошуку і заміни рядка за шаблоном.

У PHP використовується назва PCRE (Perl Compatible Regular Expressions - перл сумісні регулярні вирази). У цій статті я постараюся розкрити потенціал, це потужний інструмент програміста. Не намагайтеся зрозуміти все відразу, вбирайте порціями і приходьте за добавкою.

Простий тест регулярних виразів можна робити на сайті regex101.com

почнемо

створимо рядок

<?php
$string = 'abcdefghijklmnopqrstuvwxyz0123456789_site4study.com_абвгде_кіт';

// вивід
echo $string ;

?>

Якщо нам потрібно просто дізнатися чи є шаблон ' abc ' в рядку $string ми можемо накидати такий код: 

<?php
$string = 'abcdefghijklmnopqrstuvwxyz0123456789_site4study.com_абвгде_кіт';
echo preg_match('#abc#', $string);     //  1
?>

Цей код виведе '1'. Тому що він знайшов 1 (одне) входження шаблону в рядку.
Якщо шаблон в рядку не виявлено, preg_match поверне 0. При знаходженні першого входження, функція відразу повертає результат! Подальший пошук не продовжується (див. preg_match_all ).


Знаходження початку рядка

Тепер ми бажаємо дізнатися, чи починається рядок з ' abc '.
Символ початку рядка в регулярці - ' ^ '  ( caret - знак вставки ).

приклад:

<?php
$string = 'abcdefghijklmnopqrstuvwxyz0123456789_site4study.com_абвгде_кіт';

// тест на початок строки
if (preg_match('/^abc/', $string)) {
// OK, строка починається з abc
    echo 'The string begins with abc';
} else {
    echo 'это фэйл';
}

?>

Приклад виведе:
The string begins with abc

Обертаючі слеші - роздільники, містять регуряний вираз. Це можуть бути будь-які парні символи,
наприклад @ regex @ , # regex # , / regex / і т.д.
Символ ^ відразу після першого роздільника вказує що вираз починається спочатку рядка і ніяк інакше.


Що робити з регістром символів

Перепишемо код, щоб він шукав рядок ' ABC ':

<?php
$string = 'abcdefghijklmnopqrstuvwxyz0123456789_site4study.com_абвгде_кіт';
echo preg_match("#^ABC#", $string) ? 'Співпадіння' : 'Співпадінь немає';
?>

Скрипт поверне:
Співпадінь немає

Все тому що пошук регістру залежний. Шаблон ' abc ' не теж саме що ' ABC '.
Щоб знайти обидва варіанти, потрібно використовувати модифікатор. У регулярних виразах для цього застосовується модифікатор ' i ', який потрібно вказати за закриваючим роздільником регулярного виразу.

<?php
$string = 'abcdefghijklmnopqrstuvwxyz0123456789_site4study.com_абвгде_кіт';
if (preg_match('#^ABC#i', $string)) {
    echo 'Співпадіння, строка починаєтся з abc';
} else {
    echo 'строка не співпадає';
}
?>

Тепер скрипт знайде патерн ' abc '. Також тепер будуть потрапляти під шаблон
такі рядки abc, ABC, Abc, aBc , і т.д.

Пізніше буде розказано докладніше про модифікатори.


Як вказати в паттерні кінець рядка

Робиться це так само як і у випадку з пошуком початку рядка.
Поширена помилка, допускається багатьма програмістами - використання символу $ для вказівки кінця рядка в шаблоні.
Це невірно, правильне рішення - використовувати твердження \z .
Подивіться на цей код

<?php
$string = 'abcdefghijklmnopqrstuvwxyz0123456789_site4study.com_абвгде_кіт';
echo preg_match('#^foo$#', 'foo\n');    //  0
?>

Сніппет поверне true , тому що $ = \z , що в свою чергу можна описати виразом ( ?=\z|\n\z ).
Коли нам потрібно отримати в результаті рядок без "роздільників рядків", $ не повинен використовуватися.
Також $ спіпададає більше одного разу з модифікатором /m , на противагу \z . Змінимо трохи код, видалимо каретку ( ^ ) на початку патерну і додамо \z в кінці, також приберемо залежність від регістра модифікатором /i .

<?php
$string = 'abcdefghijklmnopqrstuvwxyz0123456789_site4study.com_абвгде_кіт';

// паттерн в кінці строки
if (preg_match('#кіт\z#i', $string)) {
    echo 'Збіг, рядок закінчується на кіт';
} else {
    echo 'не найдено';
}
?>

Результат скрипта:

Збіг, рядок закінчується на кіт

Тому що ми визначили кінець рядка кіт . Ось так.


Мета символи

Раніше ми експериментували з простими регулярками. Познайомилися з кареткою ( ^ ) і доларом ( $ )
Ці символи імєєют особливе значення. Каретка ( ^ ) позначає початок строки і долар ( $ ) - її кінець.
Такі символи в купі з іншими спеціальними символами називаються мета символами (meta characters).

Список мета символів в регулярних виразах:

. (Крапка, Full stop)
^ (Каретка, Carat)
* (Зірочка, Asterix)
+ (Plus)
? (Question Mark)
{ (Opening curly brace)
[ (Opening brace)
] (Closing brace)
\ (Backslash)
| (логічне АБО, Pipe)
( (Opening parens)
) (Closing parens)
} (Closing curly brace) 

Розберемо всі символи на прикладах.
Якщо вам потрібно скласти шаблон в якому міститься такий символ, його необхідно екранувати (див. preg_quote )
Наприклад шаблон: "1+1" , потрібно записати якось так:

<?php
// приклад
$string = '1+1=2';

if (preg_match("#^1\+1#i", $string)) {   // \+  екрануємо спеціальний знак + знаком \
    echo 'The string begins with 1+1';
} else {
    echo 'false';
}
?> 

Результат скрипта:
The string begins with 1+1

Тому що інтерпретатор проігнорував спеціальне значення символу " + ", позначеного символом екранування " \ " ( бекслеш ).
Якби ми не додали екранування до плюса, то preg_match("#^1+1#i", $string) не знайшов би збігів з шаблоном.
Сам бекслеш в свою чергу теж потрібно екранувати, якщо ми шукаємо саме цей символ " \\ ".


Що означають інші мета символи

Квадратні дужки [] означають "строковий клас".
Символьний клас. Це просто набір символів, які повинні співпасти в шуканому рядку.
Вони можуть записуватися індивідуально (по одному):

[abcdef]

Або як діапазон, розділений символом " - ":

[a-f]

<?php
$string = 'big' ;

// шукаємо шаблон
echo preg_match('#b[aoiu]g#', $string , $matches);  //  1
print_r($matches);  //  Array ( [0] => big ) // знайдені співпадіння

?>

Результат скрипта:
return 1

Тому що preg_match() знайшов збіг.
Цей код також знайде збіг з рядками 'bag' 'bog' 'big' , але не з 'beg' .
Набір символів [a-f] рівнозначний такому запису [abcdef] . Словами формулюється так [від 'a' до 'f'] .
Ще раз повторю, вирази чутливі до регістру, і [AF] не теж саме що і [af] .

Мета символи не працюють всередині класів, тому їх не потрібно екранувати всередині квадратних дужок [...] .
Наприклад клас [abcdef$] співпаде з символами abcdef$ . Долар ( $ ) всередині класу - це простий бакс знак долара без будь-якого спеціальної мета-властивості.

Є правда виключення з правил:
Одна з корисних функцій регулярних виразів - можливість вказати шаблон який НЕ збігається з діапазоном символів .
Щоб це зробити, потрібно використовувати каретку ( ^ ) першим символом класу.
Знайдемо будь-які символи, крім "b":

<?php
$string = 'abcefghijklmnopqrstuvwxyz0123456789';

// робимо пошук
preg_match('#[^b]#', $string, $matches);

// виведемо всі співпадіння в циклі foreach
foreach ($matches as $key => $value) {
    echo $key . ' -> ' . $value;       //  0 -> a
}
?>

Результат скрипта:
0 -> a

Тут preg_match() знайшов перший збіг з шаблоном #[^b]# .
Змінимо скрипт і використаємо preg_match_all() для знаходження всіх входжень відповідних шаблону  #[^b]# .

<?php
$string = 'abcefghijklmnopqrstuvwxyz0123456789';

// шукаємо ВСІ співпадіння
preg_match_all('#[^b]#', $string, $matches);

// виведемо всі співпадіння в цикле foreach
foreach ($matches[0] as $value) {
    echo $value;    //  acefghijklmnopqrstuvwxyz0123456789
}
?>

Результат скрипта:
acefghijklmnopqrstuvwxyz0123456789

Виведе всі символи, які НЕ збігаються з шаблоном "b".
Так ми можемо відфільтрувати всі цифри в рядку:

<?php
$string = 'abcefghijklmnopqrstuvwxyz0123456789';

// всі символи які не являються цифрами від 0 до 9
preg_match_all('#[^0-9]#', $string, $matches);

foreach ($matches[0] as $value) {
    echo $value;    //  abcefghijklmnopqrstuvwxyz 
}
?>

Результат скрипта:
abcefghijklmnopqrstuvwxyz

Шаблон [^0-9] розшифровується як все НЕ включаючи цифри від 0 до 9 .

Метасимвол бекслеш ( \ ).

Основне значення - екранування інших метасимволов.

<?php
// create a string
$string = 'This is a [templateVar]';

// try to match our pattern
preg_match_all('#[\[\]]#', $string, $matches);

// loop through the matches with foreach
foreach ($matches[0] as $value) {
    echo $value . '<br>';   //  [ ]
}
print_r($matches);  //  Array ( [0] => Array ( [0] => [ [1] => ] ) )

?>

Результат скрипта:
[ ]

Тут ми хотіли знайти всі символи [] . Без екранування шаблон виглядав би так - '#[[]]#' ,
але ми додали бекслеші до дужок [] , щоб скасувати їх мета-статус .
Також, наприклад, вчинимо з шляхом до файлу.
c:\dir\file.php
У паттерні будемо використовувати роздільник "\\" .

Бекслеш також використовується в рядках для вказівки спеціальних послідовностей: \n, \r і інших.

Ще він розділяє неймспейси!

Наступний символ ' . ' ( крапка ).

`Крапка ` збігається з будь-яким символом крім символів розриву рядка \r або \n .
За допомогою крапки ми можемо знайти будь-який одиночний символ , за винятком розриву рядка.
Щоб крапка також збігалася з переведенням каретки і розривом рядка, можна використовувати прапор /s .

Шукаємо одиночний символ

<?php
$string = 'box at noon taxes';

echo preg_match('#b.x#', $string, $matches);    //  1
print_r($matches);  //  Array ( [0] => box )
?>

Результат скрипта:
1

preg_match() знайшов один збіг. Приклад також спрацює з bax, bix, box, bux, і bx, але не співпаде з "btix".

Тепер спробуємо знайти \n .

<?php
// create a string
$string = 'box' . "\n" . 'at' . "\n" . 'noon' . "\n" . 'taxes' . "\n";

// echo the string
echo nl2br($string);    //  convert \n to <br> tag

/*
box
at
noon
taxes
*/

// look for a match
echo preg_match_all('#\s#', $string, $matches);     //  4

?>

Результат скрипта:

box
at
noon
taxes
4

preg_match_all() знайшов 4 збіги розриву рядка "\n " тому що ми використовували прапор \s .

Наступний чарівний символ - зірочка ( * ) asterisk
Збігається з нулем і / або БІЛЬШЕ ( 0 -  ... )  входжень шаблону, що знаходиться перед зірочкою.
* означає опціональний шаблон - допускається що символи можуть бути, а також можуть бути і відсутніми в рядку.
Так шаблон .* збігається з будь-якою кількістю будь-яких символів .

приклад:

<?php
// create a string
$string = 'php';

// look for a match
echo preg_match('#ph*p#', $string, $matches);   //  1

print_r($matches);  //  Array ( [0] => php )

?>


Результат скрипта:
1

Знайшовся один збіг. У прикладі це один символ "h ".
Приклад також співпаде також з рядком "pp " (нуль символів "h "), і "phhhp " (три символи "h ").

Добралися до мета символу символу " + "

Плюс майже теж саме що і зірочка, за винятком того що плюс збігається з ОДНИМ і БІЛЬШЕ символом ( 1 - ... ).
Так в прикладі зірочка " * " збіглася з рядком 'pp ', з плюсом " + " таке не пройде.

<?php
// create a string
$string = 'pp';

// look for a match
echo preg_match('#ph+p#', $string, $matches);   //  0
print_r($matches);  //  Array ()

?>

Результат скрипта:
0
Тому що жодного символу "h ".


Наш партнер:
beta test mp3 playlist downloader