Язык программирования PHP

         

Подвыражения (подшаблоны)


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

В РВ подшаблоны выделяют, заключая в круглые скобки. Для их обозначения кроме термина «подшаблон» также используют термин «подвыражение». Подшаблоны могут быть вложенными. Выделение части регулярного выражения в виде регулярного подвыражения делает следующее.

  1. Локализует множество альтернатив.

    Например, шаблон

    жар(кое|птица|)

    совпадает с одним из слов «жаркое», «жарптица» и «жар». Тогда как без скобок это было бы «жаркое», «птица» и пустая строка.

  2. Устанавливает подшаблон как «захватывающий» подшаблон. Это значит, что, когда какая-то подстрока в тексте совпала с шаблоном, все подстроки, которые совпали с подшаблонами этого РВ, тоже возвращаются в качестве результата. Скобки, обозначающие начало подшаблона, пересчитываются слева направо (начиная с 1) для того, чтобы узнать, сколько подшаблонов нужно захватить.

    Например, имеется такой шаблон:

    победитель получит ((золотую|позолоченный) (медаль|кубок))

    и строка, в которой ищутся совпадения с этим шаблоном: «победитель получит золотую медаль». Тогда кроме этой фразы будут еще захвачены и выданы как результаты поиска следующие совпадения в подвыражениях: «золотую медаль», «золотую», «медаль», пронумерованные 1, 2, 3 соответственно.

Однако это не всегда удобно. Для того чтобы избавиться от «захватывающего» эффекта подвыражения, после открывающей скобки пишут «?:». Тогда это подвыражение в результат поиска не включается и при нумерации остальных подшаблонов с «захватывающим» эффектом не учитывается.

победитель получит ((?:золотую|позолоченный) (медаль|кубок))

Пример 13.1. Применение ?: (html, txt)

Тогда в условиях предыдущего примера получим искомую строку «победитель получит золотую медаль» и строки «золотую медаль», «медаль», пронумерованные 1 и 2 соответственно.

Если в html-файле название находится после <body> и отделено от него только пробелами или переводами строк, заключено в тег <h1> и после него тоже может идти сколько-то пробелов и переводов строк, то его можно найти с помощью следующего скрипта:

<? //считываем файл в строку $str = file_get_contents('1.htm'); $pattern = "/<body.*?>[\n\s]*<h1>". "(.*?)<\/h1>[\n\s]*/m"; // осуществляем поиск $n = preg_match_all ($pattern, $str, $res); echo $res[1][0]; // выводим заголовок ?>

Пример 13.2. Поиск названия в html-файле (html, txt)

Заметим, что здесь выводится первое захваченное подвыражение, поскольку нам интересно только само название, а не все РВ. Так как в этом РВ есть только одно подвыражение, то его значение содержится в нулевом элементе первого массива результатов.



Содержание раздела