Приднестровская поддержка XOOPS
В предыдущем разделе мы рассмотрели регулярные выражения POSIX. Кроме формата POSIX в языке РНР существует поддержка Perl-совместимых регулярных выражений (PCRE, Perl-compatible Regular Expression). Именно формат PCRE следует использовать при работе с однобайтовыми кодировками, а также с кодировкой UTF-8.
Шаблон PCRE представляет собой строку, заключенную в кавычки или апострофы, внутри которой между двумя ограничителями указывается регулярное выражение. За последним ограничителем может быть указан модификатор. В качестве ограничителя могут служить одинаковые символы или парные скобки.
'/<Регулярное выражение>/[<Модификатор>]'
'#<Регулярное выражение>#[<Модификатор>]'
'"<Регулярное выражение>"[<Модификатор>]'
'{<Регулярное выражение>}[<Модификатор>]'
'(<Регулярное выражение>)[<Модификатор>]'
В параметре <модификатор> могут быть указаны следующие флаги (или их комбинация):
□ i — поиск без учета регистра;
□ m — поиск в строке, состоящей из нескольких строк, разделенных символом новой строки. Символ Л соответствует привязке к началу каждой подстроки, а символ $ соответствует позиции перед символом перевода строки. Метасимвол "точка" соответствует любому символу, кроме символа перевода строки (\п);
□ s — однострочный режим. Символ А соответствует привязке к началу строки, а символ $ соответствует концу строки. Метасимвол "точка" соответствует любому символу, в том числе и символу перевода строки;
□ х — разрешает использовать в регулярном выражении пробельные символы и однострочные комментарии, начинающиеся с символа #;
□ е — указывает, что в строке для замены в функции preg_repiace () указано выражение языка РНР, которое необходимо предварительно вычислить. Вместо этого флага лучше использовать функцию preg_replace_callback();
□ u — используется для обработки строк в кодировке UTF-8.
Метасимволы, используемые в регулярных выражениях PCRE:
□ ^ — привязка к началу строки (назначение зависит от модификатора);
□ $ — привязка к концу строки (назначение зависит от модификатора);
□ \A — привязка к началу строки (не зависит от модификатора);
□ \z — привязка к концу строки (не зависит от модификатора);
□ [] — позволяет указать символы, которые могут встречаться на этом месте в строке. Можно перечислять символы подряд или указать диапазон через тире;
□ [^] — позволяет указать символы, которые не могут встречаться на этом месте в строке. Можно перечислять символы подряд или указать диапазон через тире;
□ n|m — соответствует одному из символов п или m;
□ . (точка) — любой символ, кроме символа перевода строки (\п). Если используется модификатор s, то метасимвол "точка" соответствует всем символам, включая символ перевода строки. Внутри квадратных скобок точка не имеет специального значения.
Кроме того, в регулярных выражениях PCRE можно использовать следующие стандартные классы:
□ \d — соответствует любой цифре;
□ \w — соответствует любой букве или цифре;
□ \s — любой пробельный символ (пробел, табуляция, перевод страницы, новая строка или перевод каретки);
□ \d — не цифра;
□ \w — не буква и не цифра;
□ \s — не пробельный символ.
Также можно использовать стандартные классы регулярных выражений формата POSIX.
Квантификаторы, используемые в регулярных выражениях PCRE, позволяют задать число повторов предшествующего символа или выражения:
□ {n} — n вхождений символа в строку;
□ {п,} — п или более вхождений символа в строку;
□ {n,m} — не менее n ине более т вхождений символа в строку. Числа указываются через запятую без пробела;
□ * — ноль или большее число вхождений символа в строку;
□ + — одно или большее число вхождений символа в строку;
□ ? — ни одного или одно вхождение символа в строку.
Регулярные выражения PCRE можно использовать в нескольких функциях.
□ preg_grep(<Шаблон>, <Массив>, [PREG_GREP_INVERT]) возвращает новый массив, состоящий из элементов <массива>, которые соответствуют <шаблону>. Индексы массива сохраняются. Если указан флаг PREG_GREP_INVERT, то возвращается массив значений, не соответствующих шаблону. В качестве примера получим все элементы массива, состоящие только из цифр, и наоборот:
$arr = array(20, 54, "Текст", 457);
$pattern = '/^[0-9]+$/s';
$arr2 = preg_grep($pattern, $arr);
echo implode(" - ", $arr2);
// Выведет: 20 - 54 - 457
echo "<br>";
$arr3 = preg_grep($pattern, $arr, PREG_GREP_INVERT);
echo implode(" - ", $arr3);
// Выведет: Текст
□ preg_match() ищет первое совпадение с шаблоном в заданной строке. Функция имеет следующий формат:
preg_match(<Шаблон>, <Строка>, [<Массив совпадений>], [<Флаг>],
[<Смещение от начала строки>]);
Функция возвращает 0, если совпадение не найдено, и 1 в случае соответствия шаблону. Если указан параметр <массив совпадений>, то первый элемент массива будет содержать фрагмент, полностью соответствующий шаблону, а остальные элементы массива — это фрагменты, заключенные в шаблоне в круглые скобки.
В качестве примера проверим E-mail на соответствие шаблону:
$emails = 'unicross@mail.ru';
$pattern = '/^([a-z0-9_.-]+)@(([a-z0-9-]+\.)+[a-z]{2,6})$/is';
$arr = array();
if (preg_match($pattern, $emails, $arr)) {
echo 'E-mail ' . $arr[0] . ' соответствует шаблону';
echo '<br>ящик: ', $arr[1], ' домен: ', $arr[2];
}
else {
echo 'E-mail не соответствует шаблону';
}
Этот пример выведет код HTML, который отображается так:
Элемент массива $агг [0] — это полный текст, соответствующий шаблону. Элемент $arr[1] соответствует ([a-z0-9_.-]+), а элемент $агг[2] соответствует шаблону во вторых круглых скобках (([a-z0-9-]+\.)+[a-z]{2,6})
Если какой-либо фрагмент заносить в массив не надо, то после открывающей круглой скобки следует указать комбинацию символов ?:.
Например,
$emails = 'unicross@mail.ru';
$pattern = '/^(?:[a-z0-9_.-]+)@(([a-z0-9-]+\.)+[a-z]{2,6})$/is';
$arr = array();
if (preg_match($pattern, $emails, $arr)) {
echo 'E-mail ' . $arr[0] . ' соответствует шаблону';
echo '<br>домен: ', $arr[1];
}
else {
echo 'E-mail не соответствует шаблону';
}
выведет код, отображающийся в Web-браузере так:
В этом примере элемент массива $arr[1] соответствует фрагменту уже не в первых круглых скобках, а во вторых.
Если в параметре <Флаг> указано значение PREG_OFFSET_CAPTURE, то для каждого найденного фрагмента будет указана его позиция в исходной строке. Для примера получим текст между одинаковыми парными тегами и выведем смещение относительно начала строки:
$str = "<b>Текст</b>";
$pattern = '#<([^>])>(.*)</\1>#s';
$arr = array();
if (preg_match($pattern, $str, $arr, PREG_OFFSET_CAPTURE)) {
echo 'Фрагмент: ', $arr[2][0], '<br>';
echo 'Смещение: ', $arr[2][1];
}
Этот пример использует механизм обратных ссылок. К найденному фрагменту в круглых скобках внутри шаблона можно обратиться, указав его порядковый номер после слэша, например, \1 соответствует ([^>]).(1)
□ preg_match_all() ищет все совпадения с шаблоном в заданной строке. Функция имеет следующий формат:
preg_match_all(<Шаблон>, <Строка>, [<Массив совпадений>],
[<Флаг>], [<Смещение от начала строки>]);
Функция возвращает количество найденных совпадений с шаблоном (или 0, если совпадения не найдены).
Если в параметре <Флаг> указано значение PREG_PATTERN_ORDER, тo массив совпадений будет содержать элементы, упорядоченные по порядковому номеру фрагмента, заключенного в шаблоне в круглые скобки. Нулевой элемент массива будет содержать список полных совпадений с шаблоном. В качестве примера получим все значения между тегами <b> и </b>:
$str = "<b>Значение1</b>Лишнее значение<b>Значение2</b>";
$pattern = '#<b>(.*)</b>#is';
$arr = array();
preg_match_all($pattern, $str, $arr, PREG_PATTERN_ORDER);
$count = count($arr[1]);
for ($i=0; $i<$count; $i++) {
echo $arr[1][$i] . "<br>";
}
Вместо желаемого результата мы получим
Значение1</b>Лишнее значение<b>Значение2<br>
Такое поведение квантификаторов называется "жадностью". При поиске соответствия ищется самая длинная подстрока, соответствующая шаблону, и не учитываются более короткие соответствия. В нашем случае самой длинной подстрокой является вся строка. Чтобы ограничить эту "жадность", необходимо после символа * указать символ ?.
Если в параметре <Флаг> указано значение PREG_SET_ORDER, тo массив совпадений будет содержать элементы, упорядоченные по номеру совпадения. Каждый элемент массива будет содержать список совпадений фрагментов, заключенных в шаблоне в круглые скобки. Нулевой элемент массива будет содержать полное совпадение с шаблоном. В качестве примера получим все значения между тегами <b> и </b> с учетом "жадности" квантификаторов:
$str = "<b>Значение1</b>Лишнее значение<b>Значение2</b>";
$pattern = '#<b>(.*?)</b>#is';
$arr = array();
preg_match_all($pattern, $str, $arr, PREG_SET_ORDER);
$count = count($arr);
for ($i=0; $i<$count; $i++) {
echo $arr[$i][1] . "<br>";
}
Этот код выведет то, что мы искали:
Значение1<br>Значение2<br>
Ограничить "жадность" всех квантификаторов в шаблоне позволяет модификатор U. Обратите внимание на регистр модификатора. Буква должна быть прописной:
$pattern = '#<b>(.*)</b>#isU';
Если к флагам PREG_PATTERN_ORDER и PREG_SET_ORDER добавить значение PREG_OFFSET_CAPTURE, то для каждого найденного фрагмента будет указана его позиция в исходной строке:
$str = "<b>Значение1</b>Лишнее значение<b>Значение2</b>";
$pattern = '#<b>(.*?)</b>#is';
$arr = array();
preg_match_all($pattern, $str, $arr,
PREG_SET_ORDER | PREG_OFFSET_CAPTURE);
echo "<pre>";
print_r($arr);
echo "</pre>";
Код HTML, выведенный в этом примере, будет отображен в Web-браузере так:
Array
(
[0] => Array
(
[0] => Array
(
[0] => Значение1
[1] => 0
)
[1] => Array
(
[0] => Значение1
[1] => 3
)
)
[1] => Array
(
[0] => Array
(
[0] => Значение2
[1] => 31
)
[1] => Array
(
[0] => Значение2
[1] => 34
)
)
)
Здесь основной вывод был осуществлен функцией print_r(), предназначенной для вывода массивов, в том числе вложенных. (2)
□ preg_replace() ищет все совпадения с шаблоном и заменяет их указанным значением. Функция имеет следующий формат:
preg_replace(<Шаблон>, <Новый фрагмент>, <Исходная строка>,
[<Лимит>]);
Функция возвращает измененную строку. Если совпадения не найдены, то функция вернет исходную строку. Первые три параметра могут быть одномерными массивами. Если указан параметр < Лимит >, то функция заменит только указанное количество первых совпадений с шаблоном.
В качестве примера возьмем два тега и поменяем имена тегов местами:
$str = "<br><td>";
$pattern = '#<(\w+)><(\w+)>#is';
$repl = '<$2><$1>';
$str2 = preg_replace($pattern, $repl, $str);
echo htmlspecialchars($str2);
// Выведет в окне Web-браузера: <td><br>
Обратиться к найденному фрагменту в круглых скобках можно не только с помощью синтаксиса $п, но и указав номер скобок, перед которым стоят два слэша (\\п):
$str = "<br><td>";
$pattern = '#<(\w+)><(\w+)>#is';
$repl = '<\\2><\\1>';
$str2 = preg_replace($pattern, $repl, $str);
echo htmlspecialchars($str2);
// Выведет в окне Web-браузера: <td><br>
Чтобы отделить номер скобки от последующего текста, необходимо заключить номер в фигурные скобки (\${2}).
Если в шаблоне указан флаг е, то внутри выражения для замены можно использовать выражения языка РНР. В качестве примера поменяем теги местами и выведем названия тегов строчными буквами:
$str = "<BR><TD>";
$pattern = '#<(\w+)><(\w+)>#ise';
$repl = "'<' . strtolower('$2') . '><' . strtolower('$1') . '>'";
$str2 = preg_replace($pattern, $repl, $str);
echo htmlspecialchars($str2);
// Выведет в окне Web-браузера: <td><br>
□ preg_replace_callback() выполняет поиск по шаблону и замену с использованием функции обратного вызова. Функция имеет следующий формат:
preg_replace_callback(<Шаблон>, <Имя функции>,
<Строка для замены >, [<Лимит>]);
В отличие от preg_replace() функция preg_replace_callback() передает функции, указанной в параметре <Имя функции>, найденные совпадения. Результат, возвращаемый этой функцией, служит фрагментом для замены.
Переделаем наш предыдущий пример и используем функцию обратного вызова:
$str = "<BR><TD>";
$pattern = '#<(\w+)><(\w+)>#is';
$str2 = preg_replace_callback($pattern, "f_replace", $str);
echo htmlspecialchars($str2);
// Выведет в окне Web-браузера: <td><br>
function f_replace($arr) {
$repl = '<' . strtolower($arr[2]);
$repl .= '><' . strtolower($arr[1]) . '>';
return $repl;
}
Нулевой элемент массива $arr будет содержать полное соответствие шаблону, а последующие элементы соответствуют фрагментам, заключенным в шаблоне в круглые скобки.
□ preg_split() разбивает строку по шаблону и возвращает массив подстрок. Функция имеет следующий формат:
preg_split(<Шаблон>, <Исходная строка>, [<Лимит>], [<Флаг>]);
В параметре <Флаг> могут быть указаны следующие значения (или комбинация значений, соединенных оператором |):
• PREG_SPLIT_NO_EMPTY — функция вернет только непустые подстроки;
• PREG_SPLIT_DELIM_CAPTURE — фрагмент, заключенный в шаблоне в круглые скобки, также будет возвращаться;
• PREG_SPLIT_OFFSET_CAPTURE — для каждой найденной подстроки будет указана ее позиция в исходной строке.
Например, разбить E-mail на составные части можно так:
$str = 'unicross@mail.ru';
$arr = preg_split('/[@.]/', $str);
$count = count($arr);
for ($i=0; $i<$count; $i++) {
echo $arr[$i] . "<br>";
} // Выведет unicross<br>mail<br>ru<br>
Если не требуется указания шаблона, то вместо функции preg_split() лучше использовать функцию explode().
При использовании флага preg_offset_capture изменился формат массива $агг:
$агг[0][0] => "<Ь>Текст</Ь>"
$агг [0] [1] => 0
$агг [1] [0] => "Ь"
$агг [1] [1] => 1
$агг [2] [0] => "Текст"
$агг[2][1] => 3
Отправитель | Нити |
---|
8 пользователь(ей) активно (2 пользователь(ей) просматривают Инструкции)
Участников: 0 Гостей: 8 далее... |