базовый курс

ГРУППА КУРСА

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

Написание регулярных выражений

В учебнике JavaScript подробно рассматривалось написание регулярных выражений. Синтаксис регулярок практически совпадает в JavaScript и PHP. Если Вы ещё не изучали регулярные выражения, то Вам нужно с ними ознакомиться. В частности, Вам нужно изучить эти темы:

Написание регулярных выражений

Классы

Квантификаторы

Метасимволы

Конечно написание регулярных выражений в JavaScript и PHP имеет отличия. В PHP оно более сложное и имеет дополнительные возможности. Но они сложнее, чем обычные регулярные выражения и не рассматриваются в этом учебнике. Кроме того, многие термины отличаются. Например флаги называются модификаторами. Однако допустимо использование разных терминов и в этом не будет ошибки. В PHP нет флага g, потому что нужное количество совпадений указывается в функциях. Есть одно отличие, которое нужно учитывать. В PHP регулярное выражение - это строка и она пишется в кавычках.

Поиск подстроки

Функция preg_match() ищет подстроку с использованием регулярного выражения. Возвращает:

1, если есть хотя бы одно совпадение

0, если совпадений нет

false при возникновении ошибки

Эта функция находит только первое совпадение.

preg_match (RegExp, строка, результат, флаг, смещение)

Параметры:

RegExp - регулярное выражение

строка - строка в которой производится поиск

результат - массив, в который записывается найденная подстрока.

флаг - если указать значение PREG_OFFSET_CAPTURE, то в результат добавится позиция первого символа найденной подстроки

смещение - позволяет искать не с начала строки, а с указанной позиции

Обязательны первые два параметра

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

Найдём в строке слово "задача" в разных падежах:

+
1
2
<?php
header('Content-type: text/html; charset=utf-8');
3
4
5
6
$str = 'В книге есть задачи. Всего 5 задач';
$regexp = '/задач[ёа-я]*/i';
preg_match($regexp, $str, $res);
print_r($res);

Если в функции preg_match() использовать флаг, то массив с результатом становится двухмерным. В нём будет подстрока и её позиция. Добавим флаг в функцию:

5
preg_match($regexp, $str, $res, PREG_OFFSET_CAPTURE);

Обратите внимание, если в строке есть русский текст, то позиция подстроки определяется неправильно. Это происходит потому, что русские символы занимают больше одного байта. Подробнее об этом сказано теме о строках. В PHP есть функции для работы с регулярными выражениями в многобайтных кодировках. Они работают по-другому, но позволяют выполнить все основные действия.

Функция preg_match_all() выполняет те же действия, но находит все совпадения. Параметры те же самые. Найдём все вхождения слова "задача" в строке:

7
8
9
preg_match_all($regexp, $str, $res, PREG_OFFSET_CAPTURE);
echo '<br>';
print_r($res);

Замена подстроки

Функция preg_replace() находит подстроку по регулярному выражению и заменяет её на другую. Возвращает строку с изменениями.

preg_replace (RegExp, новая подстрока, строка, число замен, цифра)

Параметры:

RegExp - регулярное выражение

новая подстрока - строка на которую заменяется найденная подстрока

строка - строка в которой производится замена

число замен - максимально разрешённое количество замен. Дальнейшие замены производится не будут. Значение -1 означает, что количество не ограничено. Необязательный параметр

цифра - позволяет указать переменную, в которую будет записано количество произведённых замен

Уберём нумерацию из текста:

10
11
12
13
$str = '1 - апельсины, 2 - бананы, 3 - яблоки, 4 - киви';
$regexp = '/\d+ - /';
echo '<br>';
echo preg_replace($regexp, '', $str);

Найденную подстроку можно вставить в новую подстроку. Ссылка на неё пишется так:

$0

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

15
16
17
18
$str = 'width: 100; height: 50;';
$regexp = '/\d+/';
echo '<br>';
echo preg_replace($regexp, '$0px', $str);

Найденную строку можно вставлять по частям. Для этого паттерн нужно разделить на части. Каждая часть должна быть в скобках. Эти части называются подмаски. Чтобы вставить первую часть, нужно написать: $1, чтобы вставить вторую часть - $2 и так далее. Поменяем запятую на точку в дробных числах:

20
21
22
23
$str = 'От точки A до точки B 1,35 км, а от C до D 3,2 км';
$regexp = '/(\d+),(\d+)/';
echo '<br>';
echo preg_replace($regexp, '$1.$2', $str);

Иногда бывает нужно сразу после кода подмаски написать число. Тогда два числа сливаются. В этой ситуации код подмаски можно написать с использованием фигурных скобок.

${1}

В функции preg_replace() вместо начальной строки можно указать массив. Замена будет произведена во всех его элементах. Функция вернёт массив с изменениями.

Разделение строки

Функция preg_split() делит строку на части по разделителю, указанному в регулярном выражении. Возвращает массив из частей строки.

preg_split (RegExp, строка, число элементов, флаги)

Параметры:

RegExp - регулярное выражение, определяющее разделитель

строка - строка, которая разделяется

число элементов - позволяет указать максимальное количество элементов в массиве. Когда достигается это количество, вся оствшаяся часть строки помещается в последний элемент массива. Значения NULL, 0, -1 указывают, что количество элементов не ограничено (по умолчанию)

флаги - флаги, определяющие работу функции

Возможны следующие флаги:

PREG_SPLIT_NO_EMPTY - не добавляет в массив пустые значения

PREG_SPLIT_DELIM_CAPTURE - часть регулярного выражения можно поместить в скобки. Подсткора, соответствующая этой части будет добавлена в массив.

PREG_SPLIT_OFFSET_CAPTURE - в массив добавляются позиции найденных разделителей

Если флагов несколько, между ними ставится оператор |

Разделим текст на предложения. Разделителями будут знаки препинания, которые ставятся в конце предложений:

25
26
27
28
29
30
$str = 'Мы изучаем регулярные выражения. Это важная тема! Она
сложная? Да, но её нужно знать.';
$regexp = '/[!?.]/';
$ar = preg_split($regexp, $str, -1, PREG_SPLIT_NO_EMPTY);
echo '<br>';
print_r($ar);

В данном примере точка является разделителем. Она есть в конце строки. После этой точки в массив добавится пустое значение. Чтобы этого не было я добавил в функцию нужный флаг.