Регулярные выражения в PHP

Регулярные выражения (сокращенно - 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.+-]+@[a-z0-9-]+(\.[a-z0-9-]+)*/i

Аналоговые сокеты

Регулярные выражения состоят из двух типов символов:

  • специальные символы: \ []? * + {} () ^ $ /.
  • Литералы.

Представьте себе входные строки как болты, а шаблон - как набор разъемов для них (в соответствующем порядке).

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

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

  • Символ обратной косой черты \\ может заменять другой специальный символ в регулярном выражении:
  • Точка и \w - .

Совпадение со всеми символами, кроме новых строк. Если хотите проверить на соответствие точке, и только точке - \, на соответствие буквам, цифрам и нижнему подчеркиванию - \w

  • Квадратные скобки [].

Совпадение с символами внутри скобок. Поддерживает диапазоны. Некоторые примеры:
o [abc] - соответствует любым a, b или c.
o [a-z] прописные буквы.
o [0-9] любая цифра.
o [a-zA-Z] - соответствует любому буквенному символу в нижнем или верхнем регистре.
• Опционально ? Соответствие 0 или 1.
• Звездочка *.

Звездочка обозначает 0 или более символов.

• Плюс +.

Соответствие 1 или более символам.

• Фигурные скобки {}.

Минимальное и максимальное значения. Некоторые примеры синтаксиса регулярных выражений:
o {1,} не менее 1.
o {1,3} от 1 до 3.
o {1,64} от 1 до 64.

Добавим все это, чтобы получить регулярное выражение для адресов электронной почты:

/[\w.+-]+@[a-z0-9-]+(\.[a-z0-9-]+)*/i

regex

Как это выглядит в PHP:

preg_match_all(
    "/[\w.+-]+@[a-z0-9-]+(\.[a-z0-9-]+)*/i",
    $input_lines,
    $output_array
);

Использование регулярного выражения для валидации

Задача: убедиться, что вводимые данные - это то, что мы ожидаем. Цель 1: /[^\[\]\w$.]/ Цель 2: /^[0-9]{1,2}[dwmy]$/

Регулярные выражения подходят для поиска элементов, но вам нужно знать, что именно вы ищете.

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

Многие случаи лучше обрабатывать с помощью функции PHP filter_var. Например, проверка адреса электронной почты должна выполняться с помощью встроенных фильтров PHP:

filter_var(
    'bob@example.com',
    FILTER_VALIDATE_EMAIL
)

Валидация с помощью регулярных выражений

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

^ - указывает начало строки.
$ - знак доллара, который указывает конец строки.

if (!preg_match("%^[0-9]{1,2}[dwmy]$%", $_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);

Результат

11/7

Изменение форматирования даты

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

Результат

11/09/2001

Простой пример замены URL-адреса в теге <a>

$subject = 'Please visit https://php.earth/doc for more articles.';
echo preg_replace(
    '#(https?\://([^\s\./]+(?:\.[^\s\./]+)*[^\s]*))#i',
    '<a href="$1" target="_blank">$2</a>',
    $subject
);

Результат

Please visit <a href="https://php.earth/doc" target="_blank">php.earth/doc</a> for more articles.

Иногда нужно выполнить сложный поиск и замену, например, при фильтрации/проверке перед заменой. В этой ситуации может пригодиться preg_replace_callback().

Приведенное в предыдущем примере регулярное выражение может заменить только URL-адреса, начинающиеся с http или https. Но теперь нам также нужно заменить URL-адреса, начинающиеся с www. Кто-то подумает, что можно просто изменить https? \: // в подшаблоне. Например, на (?: Https? \: // | www \.), Но это не будет работать в большинстве браузеров, потому что они будут интерпретировать www.domain как относительный путь.

Поэтому в конструкторе регулярных выражений перед заменой нужно выполнить некоторые действия, добавив http://, если URL-адрес начинается с www.

function add_protocol_if_begins_with_www($matches)
{
    $url = strtolower($matches[1]) === 'www.'
        ? 'http://' . $matches[0]
        : $matches[0];
    return "<a href=\"{$url}\">{$matches[2]}</a>";
}
$subject = 'Please visit www.php.earth/doc for more articles.';
echo preg_replace_callback(
    '#(https?\://|www\.)([^\s\./]+(?>\.[^\s\./]+)*[^\s]*)#i',
    'add_protocol_if_begins_with_www',
    $subject
);

Результат

Please visit <a href="http://www.php.earth/doc" target="_blank">php.earth/doc</a> for more articles.

Проблема: ссылка @mentions и #tags
Цель: /\B@([\w]{2,})/i

Перевод статьи «Regex - regular expressions in PHP» дружной командой проекта Сайтостроение от А до Я.

21 июля 2017 в 14:55
Материалы по теме
{"url":"http://www.fastvps.ru/", "src":"/images/advbanners/fastvps.png", "alt":"Хостинг Fastvps.ru. Наш выбор!"}
Заработок