ZaLinux.ru

Поиск по нескольким строкам в PHP с функциями preg_match_all и preg_match

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

Дело в том, что нужно помнить про печатные и непечатные символы. Перевод строки — это отдельный символ, который является непечатным (хотя результаты его действия — перевод строки — видны на экране). При этом хотя про символ . (точка) хотя и пишут во многих материалах, что он соответствует любым символам, на самом деле, он соответствует всем символам кроме перевода строк. Поэтому получается, что написанное регулярное выражение, которая совпадает со строкой в одну линию, перестаёт работать для этой же строки разбитой на несколько строк.

Возьмём к примеру HTML код, из которого мы хотим извлечь данные с помощью регулярного выражения:

      <table border=0>
  <tr>
  <td>


  <h2>subject</h2>



    </td>

Представим ситуацию, что нам нужно извлечь строку subject, которая помещена в заголовке, который помещён в таблице. В приведённом выше примере специально оставлены белые пробелы и переносы строк.

Во-первых, можно воспользоваться опцией s, которая указывается после регулярного выражения. Если использовать данный модификатор, то метасимвол «.» начинает означать «любой символ», в том числе включая перевод строк.

preg_match('#<td>.*<h2>(.*?)</h2>.*</td>#s', $str, $matches);
// результат помещён в $matches[1]

Во-вторых, можно использовать экранирующую последовательность \s. Сочетание \s означает «любые белые пробелы». Поскольку пробелы могут присутствовать, а могут отсутствовать, то к \s нужно добавить квантор количества * (звёздочка), который означает «ноль или любое количество раз». В таком случае соответствующим регулярным выражением будет:

preg_match('#<td>\s*<h2>(.*?)</h2>\s*</td>#i', $str, $matches);
// результат помещён в $matches[1]

Рекомендуемые статьи:

Оставить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *