Содержимое карманов доступно не только в строке замены, но в и самой регулярке: мы можем положить что-нибудь в карман, а затем прямо в регулярке сказать, что здесь должно стоять содержимое этого кармана.
Содержимое карманов доступно по их номерам,
перед которыми стоит обратный слеш. Например,
нулевой карман будет доступен вот так: \0
,
первый карман вот так - \1
, второй
- \2
и так далее.
Уверен, что все написанное выше пока весьма туманно для вас. Это не удивительно, так какие карманы - самое малопонятное место регулярок. Давайте будем разбираться на примерах.
Пример
Пусть у нас есть вот такая строка:
<?php
$str = 'aa bb cd ef';
?>
Давайте найдем в ней все места, в которых стоят две любые одинаковые буквы подряд. Для решения задачи будем искать любую букву, класть ее в карман, а затем проверять, идет ли следующем символом содержимое этого кармана:
<?php
$res = preg_replace('#([a-z])\1#', '!', $str);
?>
В результате в переменную запишется следующее:
'! ! cd ef'
Пример
Пусть у нас есть вот такая строка:
<?php
$str = 'asxca buzxb csgd';
?>
Давайте найдем в ней все слова, в которых одинаковы первая и последняя буквы. Для решения задачи напишем следующий шаблон: буква, затем еще одна или более букв, а затем такая же буква как первая:
<?php
$res = preg_replace('#([a-z])[a-z]+\1#', '!', $str);
?>
В результате в переменную запишется следующее:
'! ! csgd'
Альтернативный синтаксис
Вместо \1
можно писать \g1
:
<?php
$res = preg_replace('#([a-z])[a-z]+\g1#', '!', $str);
?>
Можно также писать \g{1}
:
<?php
$res = preg_replace('#([a-z])[a-z]+\g{1}#', '!', $str);
?>
В фигурных скобках можно указывать отрицательные числа. В этом случае карманы будут отсчитываться с конца:
<?php
$res = preg_replace('#([a-z])([a-z])\g{-2}#', '!', $str);
?>
Практические задачи
Дана строка:
<?php
$str = 'aaa bbb ccc xyz';
?>
Найдите все подстроки, в которых есть три одинаковые буквы подряд.
Дана строка:
<?php
$str = 'a aa aaa abab bbbb';
?>
Найдите все подстроки, в которых есть две и более одинаковые буквы подряд.
Дана строка:
<?php
$str = 'aaa aaa bbb bbb ccc ddd';
?>
Найдите все подстроки, в которых есть два одинаковых слова подряд.