PHP
Регулярные выражения (regexp / PCRE)
Поиск…
Синтаксис
-
preg_replace($pattern, $replacement, $subject, $limit = -1, $count = 0);
-
preg_replace_callback($pattern, $callback, $subject, $limit = -1, $count = 0);
-
preg_match($pattern, $subject, &$matches, $flags = 0, $offset = 0);
-
preg_match_all($pattern, $subject, &$matches, $flags = PREG_PATTERN_ORDER, $offset = 0);
-
preg_split($pattern, $subject, $limit = -1, $flags = 0)
параметры
параметр | подробности |
---|---|
$pattern | строка с регулярным выражением (шаблон PCRE) |
замечания
Регулярные выражения PHP соответствуют стандартам шаблона PCRE, которые получены из регулярных выражений Perl.
Все строки PCRE в PHP должны быть заключены с разделителями. Разделителем может быть любой символ, не являющийся буквенно-цифровым, без обратного слэш-символа. Популярные разделители ~
, /
, %
например.
Шаблоны PCRE могут содержать группы, классы символов, группы символов, ожидания вперед / назад и скрытые символы.
Модификаторы PCRE можно использовать в строке $pattern
. Некоторые общие из них: i
(регистр нечувствителен), m
(многострочный) и s
(метасимвол точки содержит новые строки). Модификатор g
(global) не разрешен, вместо этого вы будете использовать preg_match_all
.
Совпадения с строками PCRE выполняются с помощью $
префиксных нумерованных строк:
<?php
$replaced = preg_replace('%hello ([a-z]+) world%', 'goodbye $1 world', 'hello awesome world');
echo $replaced; // 'goodbye awesome world'
Согласование строк с регулярными выражениями
preg_match
проверяет соответствие строки регулярному выражению.
$string = 'This is a string which contains numbers: 12345';
$isMatched = preg_match('%^[a-zA-Z]+: [0-9]+$%', $string);
var_dump($isMatched); // bool(true)
Если вы передадите третий параметр, он будет заполнен соответствующими данными регулярного выражения:
preg_match('%^([a-zA-Z]+): ([0-9]+)$%', 'This is a string which contains numbers: 12345', $matches);
// $matches now contains results of the regular expression matches in an array.
echo json_encode($matches); // ["numbers: 12345", "numbers", "12345"]
$matches
содержит массив целого совпадения, а затем подстроки в регулярном выражении, ограниченном круглыми скобками, в порядке смещения открытой скобки. Это означает, что если у вас есть /z(a(b))/
как регулярное выражение, индекс 0 содержит всю подстроку zab
, индекс 1 содержит подстроку, ограниченную внешними скобками ab
а индекс 2 содержит внутренние скобки b
.
Разделить строку на массив с помощью регулярного выражения
$string = "0| PHP 1| CSS 2| HTML 3| AJAX 4| JSON";
//[0-9]: Any single character in the range 0 to 9
// + : One or more of 0 to 9
$array = preg_split("/[0-9]+\|/", $string, -1, PREG_SPLIT_NO_EMPTY);
//Or
// [] : Character class
// \d : Any digit
// + : One or more of Any digit
$array = preg_split("/[\d]+\|/", $string, -1, PREG_SPLIT_NO_EMPTY);
Выход:
Array
(
[0] => PHP
[1] => CSS
[2] => HTML
[3] => AJAX
[4] => JSON
)
Чтобы разбить строку на массив, просто передайте строку и regexp для preg_split();
для сопоставления и поиска, добавление третьего параметра ( limit
) позволяет вам установить количество «совпадений» для выполнения, оставшаяся строка будет добавлена в конец массива.
Четвертый параметр - это ( flags
), здесь мы используем PREG_SPLIT_NO_EMPTY
который мешает нашему массиву содержать любые пустые ключи / значения.
Строка, заменяющая регулярным выражением
$string = "a;b;c\nd;e;f";
// $1, $2 and $3 represent the first, second and third capturing groups
echo preg_replace("(^([^;]+);([^;]+);([^;]+)$)m", "$3;$2;$1", $string);
Выходы
c;b;a
f;e;d
Ищет все между точками с запятой и отменяет порядок.
Глобальное соответствие RegExp
Глобальное соответствие RegExp может быть выполнено с использованием preg_match_all
. preg_match_all
возвращает все соответствующие результаты в строке темы (в отличие от preg_match
, которая возвращает только первый).
Функция preg_match_all
возвращает количество совпадений. Третий параметр $matches
будет содержать совпадения в формате, управляемом флагами, которые могут быть указаны в четвертом параметре.
Если задано массив, $matches
будет содержать массив в аналогичном формате, который вы получите с preg_match
, за исключением того, что preg_match
останавливается при первом совпадении, где preg_match_all
выполняет итерацию по строке до тех пор, пока строка не будет полностью поглощена и не вернет результат каждой итерации в многомерном массиве , формат которого может управляться флагом в четвертом аргументе.
Четвертый аргумент, $flags
, управляет структурой массива $matches
matches. Режим по умолчанию - PREG_PATTERN_ORDER
а возможные флаги - PREG_SET_ORDER
и PREG_PATTERN_ORDER
.
Следующий код демонстрирует использование preg_match_all
:
$subject = "a1b c2d3e f4g";
$pattern = '/[a-z]([0-9])[a-z]/';
var_dump(preg_match_all($pattern, $subject, $matches, PREG_SET_ORDER)); // int(3)
var_dump($matches);
preg_match_all($pattern, $subject, $matches); // the flag is PREG_PATTERN_ORDER by default
var_dump($matches);
// And for reference, same regexp run through preg_match()
preg_match($pattern, $subject, $matches);
var_dump($matches);
Первый var_dump из PREG_SET_ORDER
дает этот результат:
array(3) {
[0]=>
array(2) {
[0]=>
string(3) "a1b"
[1]=>
string(1) "1"
}
[1]=>
array(2) {
[0]=>
string(3) "c2d"
[1]=>
string(1) "2"
}
[2]=>
array(2) {
[0]=>
string(3) "f4g"
[1]=>
string(1) "4"
}
}
$matches
имеет три вложенных массива. Каждый массив представляет одно совпадение, которое имеет тот же формат, что и результат возврата preg_match
.
Второй var_dump ( PREG_PATTERN_ORDER
) дает этот результат:
array(2) {
[0]=>
array(3) {
[0]=>
string(3) "a1b"
[1]=>
string(3) "c2d"
[2]=>
string(3) "f4g"
}
[1]=>
array(3) {
[0]=>
string(1) "1"
[1]=>
string(1) "2"
[2]=>
string(1) "4"
}
}
Когда одно и то же регулярное выражение запускается через preg_match
, возвращается следующий массив:
array(2) {
[0] =>
string(3) "a1b"
[1] =>
string(1) "1"
}
Строка заменить обратным вызовом
preg_replace_callback
работает, отправляя каждую согласованную группу захвата в определенный обратный вызов и заменяя ее возвращаемым значением обратного вызова. Это позволяет нам заменять строки на основе любой логики.
$subject = "He said 123abc, I said 456efg, then she said 789hij";
$regex = "/\b(\d+)\w+/";
// This function replaces the matched entries conditionally
// depending upon the first character of the capturing group
function regex_replace($matches){
switch($matches[1][0]){
case '7':
$replacement = "<b>{$matches[0]}</b>";
break;
default:
$replacement = "<i>{$matches[0]}</i>";
}
return $replacement;
}
$replaced_str = preg_replace_callback($regex, "regex_replace", $subject);
print_r($replaced_str);
# He said <i>123abc</i>, I said <i>456efg</i>, then she said <b>789hij</b>