Регулярні вирази. Регулярні вирази PHP Php регулярні з рядка число

1.6K

Регулярні вирази (скорочено - regex) є послідовністю символів, які формують шаблони пошуку. Здебільшого вони використовують у шаблонах зіставлення з рядками.

Коротка історія

  • Все почалося в 1940-1960-х роках, коли безліч розумних людей говорили про регулярні висловлювання;
  • 1970-і роки g/re/p;
  • 1980 Perl та Генрі Спенсер;
  • 1997 PCRE (регулярні вирази, сумісні з Perl). Саме тоді почався зліт того, що ми називаємо регулярні висловлювання. PCRE надає бібліотеки майже кожної мови.

Загальне використання регулярних виразів у PHP

PHP включає три основні функції для роботи з PCRE - preg_match , preg_match_all і preg_replace .

Порівняння відповідності

Вираз повертає 1 якщо відповідність встановлено, 0 - якщо ні, і false - якщо виникає помилка:

int preg_match (string $pattern, string $subject[, array &$matches[, int $flags = 0 [, int $offset = 0 ]]]))

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

int preg_match_all (string $pattern, string $subject [, array &$matches [, int $flags = PREG_PATTERN_ORDER [, int $offset = 0 ]]]))

Заміна

Вираз повертає замінений рядок або масив ( на основі об'єкта $subject):

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

Загальне використання регулярних виразів у JavaScript

Регулярні вирази в JavaScript виглядають майже так само, як і в PHP.

Порівняння відповідності

Повертає масив збігів або null, якщо збігів не знайдено:

string.match(RegExp);

Заміна

Регулярний вираз, який повертає рядок із виконаними замінами:

string.replace(RegExp, replacement);

Особливості регулярних виразів у JavaScript

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

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

Розглянемо приклад, у якому необхідно знайти адреси електронної пошти у базі коду. Наша мета:

Аналогові сокети

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

  • Спеціальні символи: ? * + () () ^ $ / .
  • Літерали.

Уявіть собі вхідні рядки як болти, а шаблон як набір роз'ємів для них (у відповідному порядку).

Спеціальні символи

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

  • Символ зворотної косої риси може замінювати інший спеціальний символ в регулярному вираженні:
  • Крапка і w - .

Збіг з усіма символами, крім нових рядків. Якщо хочете перевірити на відповідність точці, і лише точці — , на відповідність літер, цифр і нижнього підкреслення — w

  • Квадратні дужки.

Збіг з символами всередині дужок. Підтримує діапазони. Деякі приклади:
o - відповідає будь-яким a, b або c.
o великі літери.
o будь-яка цифра.
o - відповідає будь-якому буквеному символу в нижньому або верхньому регістрі.
Опціонально? Відповідність 0 чи 1.
Зірочка*.

Зірочка позначає 0 або більше символів.

Відповідність 1 або більше символів.

Фігурні дужки ().

Мінімальне та максимальне значення. Деякі приклади синтаксису регулярних виразів:
o (1,) не менше 1.
o (1,3) від 1 до 3.
o (1,64) від 1 до 64.

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

/+@+(.+)*/i


Як це виглядає в PHP:

preg_match_all("/+@+(.+)*/i", $input_lines, $output_array);

Використання регулярного виразу для валідації

Завдання: переконатися, що дані, що вводяться - це те, що ми очікуємо. Мета 1: /[^w$.]/ Мета 2: /^(1,2)$/

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

Коли не варто використовувати регулярні вирази для перевірки?

Багато випадків краще обробляти за допомогою функції PHP filter_var. Наприклад, перевірка адреси електронної пошти повинна виконуватись за допомогою вбудованих фільтрів PHP:

filter_var(" [email protected]", FILTER_VALIDATE_EMAIL)

Валідація за допомогою регулярних виразів

Регулярні вирази в кінці рядка використовують анкори:

^ - Вказує початок рядка.
$ - Знак долара, який вказує кінець рядка.

if (!preg_match("%^(1,2)$%", $_POST["subscription_frequency"])) ( $isError = true; )

Виняткові класи символів

[^abc] — все, окрім a, b або c, включаючи нові рядки.

Приклад, який забезпечує введення лише буквено-цифрових символів, тире, крапки, підкреслення:

if (preg_match("/[^0-9a-z-_.]/i", $productCode)) ( $isError = true; )

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

Найбільш поширеними функціями PCRE для пошуку та заміни є preg_replace() і preg_replace_callback() . Але є також preg_filter() і preg_replace_callback_array() , які роблять майже те саме. Зауважте, що функція preg_replace_callback_array() доступна, починаючи з PHP7 .

Замінити слова у списку

$subject = "I want to eat some apples."; echo preg_replace("/apple|banana|orange/", "fruit", $subject);

Результат

I want to eat some fruits.

Якщо у регулярному вираженні є підшаблони ( у круглих дужках), можна замінити $N або N (де N є цілим числом > = 1), це називається «зворотне посилання».

Перестановка двох чисел

$subject = "7/11"; echo preg_replace("/(d+)/(d+)/", "$2/$1", $subject);

Результат

Зміна форматування дати

$subject = "2001-09-11"; echo preg_replace("/(d+)-(d+)-(d+)/", "$3/$2/$1", $subject);

Результат

Простий приклад заміни URL-адреси у тезі

$subject = "Please visit https://php.earth/doc for more articles."; echo preg_replace("#(https?://([^s./]+(?:.[^s./]+)*[^s]*))#i", "$2", $subject) ;

Результат

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

Ця тема досить непроста, але я постараюся у короткій формі висвітлити найважливіші моменти. Не знаю, наскільки це в мене вийде, але сподіваюся, що користь від уроку буде.
Отже, почнемо з того, що для роботи з регулярними виразами в 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», що закривається:

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

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

У цій статті надана добірка php regexp прикладів. Дуже гарна та корисна колекція прикладів регулярних виразів (regular expressions). Всі приклади регулярних виразів є прийнятними для PHP. Користуйтеся для здоров'я!

Приклад перевірки доменного імені

Даний, php сніпет перевіряє, чи є рядок допустимим доменним ім'ям.

?:.*)+):?(d+)?/?/i", $url)) ( echo "Your url is ok."; ) else ( echo "Wrong url."; )

Приклад підсвічування слова в тексті

Дуже корисний регулярний вираз для пошуку та підсвічування потрібного слова в тексті. Особливо код корисний, під час створення висновку результатів пошуку.

$text = "Сample sentence from KomunitasWeb, regex has become popular in web programming. Next we learn regex. Посилання на wikipedia, Regular expressions (abbreviated as regex or regexp, with plural forms regexes, regexps, or regexen) are written in a formal language that can be interpreted by regular expression processor"; $text = preg_replace("/b(regex)b/i", " 1", $text); echo $text;

Приклад реалізації підсвічування результатів пошуку уWordPress

Відкрийте файл search.php та знайдіть функцію the_title(). Замініть її наступним рядком:

Echo $title;

А тепер, перед заміненим рядком, вставте цей код:

\0", $title); ?>

Збережіть файл search.php і відкрийте style.css. Додайте до нього наступний рядок:

Strong.search-excerpt ( background: yellow; )

Приклад отримання зображень зHTML методом regexp

Даний шматок php коду використовує регулярні вирази, шукає всі зображення та адресу url до них.

$images = array(); preg_match_all("/(img|src)=("|")[^"">]+/i", $data, $media); unset ($ data); $data=preg_replace("/(img|src)("|"|="|=")(.*)/i","$3",$media); foreach($data as $url) ( $info = pathinfo($url); if (isset($info["extension"])) ( if (($info["extension"] == "jpg") || ($info["extension"] == "jpeg") || ($info["extension"] == "gif") || ($info["extension"] == "png")) array_push($ images, $url);

Видалення слів, що повторюються (без урахування регістру)

Чи часто зустрічаються слова, які повторюються? Тоді приклад цього регулярного виразу буде корисним.

$text = preg_replace("/s(w+s)1/i", "$1", $text);

Видалення точок, що повторюються

Те ж саме, тільки з точками, що повторюються.

$text = preg_replace("/.+/i", ".", $text);

Відповідність XML / HTML тегів

Ця проста функція приймає два аргументи: тег (відповідності якому ви хочете знайти), XML або html код.

Function get_tag($tag, $xml) ( $tag = preg_quote($tag); preg_match_all("(<".$tag."[^>]*>(.*?).")", $xml, $matches, PREG_PATTERN_ORDER); return $matches; )

Пошук XHTML/XML тегів із певними значеннями атрибутів

Цей приклад схожий на попередню функцію, тільки ви можете значно розширити пошук.

.

Function get_tag($attr, $value, $xml, $tag=null) ( if(is_null($tag)) $tag = "\w+"; else $tag = preg_quote($tag); $attr = preg_quote($ attr); $value = preg_quote($value);<(".$tag.")[^>]*$attr\s*=\s*". "(["\"])$value\\2[^>]*>(.*?)<\/\\1>/" preg_match_all($tag_regex, $xml, $matches, PREG_PATTERN_ORDER); return $matches; )

Пошук шістнадцяткових значень кольору

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

$string = "#555555"; if (preg_match("/^#(?:(?:(3))(1,2))$/i", $string)) ( echo "example 6 successful."; )

Приклад пошукуtitle на заданій сторінці

Цей цікавий приклад PHP коду з regexp шукає та повертає текст між тегами і.

Feof($fp))( $page .= fgets($fp, 4096); ) $titre = eregi(" (.*)",$page,$regs); echo $regs; fclose($fp);

Парсинг логу Apache

Більшість сайтів працюють на відомих серверах Apache. Якщо ваш сайт також працює на ньому, можна зробити парсинг лога сервера за допомогою php regexp.

//Logs: Apache web server //Successful hits to HTML files only. Застосовується для Counting number of page views. "^((?#client IP або domain name)S+)s+((?#basic authentication)S+s+S+)s+[((?#date and time)[^]]+)]s+"(?: GET|POST|HEAD) ((?#file)/[^?"]+?.html?)??((?#parameters)[^?"]+)? HTTP/+"s+(?#status code)200s+((?#bytes transferred)[-0-9]+)s+"((?#referrer)[^"]*)"s+"((?#user agent )[^"]*)"$" //Logs: Apache web server //404 помилки тільки "^((?#client IP or domain name)S+)s+((?#basic authentication)S+s+S+) s+[((?#date and time)[^]]+)]s+"(?:GET|POST|HEAD) ((?#file)[^ ?"]+)??((?#parameters)[ ^ ?"]+)? HTTP/+"s+(?#status code)404s+((?#bytes transferred)[-0-9]+)s+"((?#referrer)[^"]*)"s+"((?#user agent )[^"]*)"$"

Приклад перевірки складності пароля

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

"A(?=[-_a-zA-Z0-9]*?)(?=[-_a-zA-Z0-9]*?)(?=[-_a-zA-Z0-9]*?) [-_a-zA-Z0-9](6,)z"

Заміна текстових смайликів на графічні смайлики

Даний приклад коду змінюватиме текстовий смайлик, на ваш графічний. Цікавий та корисний php сніппет.

$texte="A text with a smiley:-)"; echo str_replace(":-)"," ", $ Texte);

Приклад регулярного виразу для отримання зображень зhtml коду

Варто сказати, що даний php код використовується в wordpress, для пошуку та обробки зображень.

post_content; $szSearchPattern = "~ ]* />~"; // Run preg_match_all до схопити всі зображення і зберегти результати в $aPics preg_match_all($szSearchPattern, $szPostContent, $aPics); // Check to see if we have at least 1 image count($aPics); if ($iNumberOfPics > 0) ( // Тут ви можете обробляти ваші зображення // У цьому прикладі вони просто виведуть на монітор for ($i=0; $i< $iNumberOfPics ; $i++) { echo $aPics[$i]; }; }; endwhile; endif; ?>

Сподіваюся, вам була корисна добірка прикладів php regexp. Якщо є цікаві доповнення або приклади регулярних виразів (PHP), пишіть у коментарях.

mixed preg_match(string pattern, string subject [, array &matches [, int flags [, int offset]]])

Шукає в заданому тексті subject збігу із шаблоном pattern

У випадку, якщо додатковий параметр matches вказаний, він буде заповнений результатами пошуку. Елемент $matches буде містити частину рядка, що відповідає входу всього шаблону, $matches - частина рядка, що відповідає першій підмасці, і так далі.

flags може приймати такі значення:

PREG_OFFSET_CAPTURE

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

Додатковий параметр flags доступний з PHP 4.3.0.

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

Примітка:Використання параметра offset не еквівалентне заміні зіставного рядка виразом substr($subject, $offset) при виклику функції preg_match_all()оскільки шаблон pattern може містити такі умови як ^ , $ або (? . Порівняйте:

У той час як цей приклад

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

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


Приклад 2. Пошук слова "web" у тексті

/*
Спеціальна послідовність \b у шаблоні означає межу слова,
отже, лише ізольоване входження слова "web" буде відповідати
масці, на відміну від "webbing" чи "cobweb".
*/
if (preg_match ("/\bweb\b/i" , "PHP is the web scripting language of choice.")) {
echo "Входження знайдено.";
) else (
echo "Входження не знайдено.";
)preg_match ("/\bweb\b/i" , "PHP is the website scripting language of choice.")) {
echo "Входження знайдено.";
) else (
echo "Входження не знайдено.";
}
?>