52568.fb2
\d{3}
задает ровно три цифры.
Сокращенные квантификаторы задают наиболее используемые количественные отношения (повторения). Они придуманы для удобства, чтобы не перегружать и без того сложные выражения лишним синтаксисом.
Исходя из исторических традиций три наиболее часто встречающихся квантификатора имеют следующие обозначения:
* эквивалентно {0,} – то есть это ноль и более повторений;
+ эквивалентно {1,} – то есть это одно и более повторений;
? эквивалентно {0,1} – то есть это ноль или одно повторение.
Есть еще один важный момент, на который стоит обратить внимание при изучении квантификаторов. По умолчанию все квантификаторы «жадные», они стараются захватить как можно больше повторений элемента. То есть если указать, что символ должен повторяться один и более раз (например, с помощью *), совпадение произойдет со строкой, содержащей наибольшее число повторений указанного символа. Это может создать проблемы, например, при попытке выделить комментарии в программе на языке Cи или PHP. Комментарии в Cи и PHP записываются между символами /* и */, внутри которых тоже могут встречаться символы * и /. И попытка выявить Си-комментарии с помощью шаблона
/\* .* \*/
в строке
/* первый комментарий */
не комментарий
/* второй комментарий */
не увенчается успехом из-за «жадности» элемента «.*» (будет найдена также строка «не комментарий»).
Для решения этой проблемы нужно написать знак вопроса после квантификатора. Тогда он перестанет быть «жадным» и попытается захватить как можно меньшее число повторений элемента, к которому он применен (квантификатор применяется к элементу, что стоит перед ним). Так что шаблон
/\* .*? \*/
успешно выделяет Си-комментарии.
В PHP существует опция PCRE_UNGREEDY, которая делает все квантификаторы «не жадными» по умолчанию и «жадными», если после них идет знак вопроса.
<?
//Рассмотрим html-файл, где имеется
//следующая строка:
$str = "<div id=1>Привет</div> ".
"<p>Текст, не заключенный в тег ".
"div</p><div id=2>Пока</div>";
// Если мы хотим найти текст,
// содержащийся между тегами div,
// естественно написать такой шаблон:
$pattern = "!<div id=1>.*</div>!si";
// Но этот шаблон слишком "жадный"
// и захватит также и текст,
// заключенный в нашем примере между
// тегами <p>. Чтобы этого избежать,
// нужно написать следующий шаблон,
// отличающийся только наличием знака
// вопроса, который запрещает
// квантификатору быть "жадным".
$pattern1 = "!<div id=1>.*?</div>!si";
// Запускаем поиск в строке $str
// совпадений с шаблонами
// $pattern и $pattern1
$s = preg_match_all ($pattern, $str,
$res);
$js = preg_match_all ($pattern1,
$str, $res1);
//выводим результаты поиска
// функция htmlspecialchars позволяет
// выводить html без
// его обработки браузером
echo "Жадный шаблон:".