Задача
Необходимо найти не первое вхождение слова, а n-ое.
Решение
Вызовите функцию preg_match_all(), чтобы занести все совпадения в массив; затем извлеките то совпадение, которое вас интересует:
preg_match_all ("/$pattern/$modifiers", $string, $matches)
foreach($matches as $match) {
print "$match\n";
}
Обсуждение
В отличие от Perl, Perl-совместимые регулярные выражения в PHP не поддерживают модификатор /g, позволяющий выполнить цикл поис-ка всех совпадений в строке за один раз. Вместо функции preg_match() здесь необходимо использовать функцию preg_match_all().
Функция preg_match_all() возвращает двумерный массив. Первый элемент содержит массив совпадений с полным шаблоном. Второй элемент также содержит массив совпадений, но на более мелком уровне подсовпадений, заключенных в круглые скобки внутри каждого полного совпадения. Так, чтобы получить третью пару к слову potato, надо извлечь третий элемент из второго элемента массива $matches:
$potatoes = 'one potato two potato three potato four';
preg_match_all("/(\w+)\s+potato\b/", $potatoes, $matches);
print $matches;
three
Вместо того чтобы возвращать массив, содержащий отдельно полные совпадения и подсовпадения, функция preg_match_all() может возвратить массив, состоящий из отдельных массивов для каждого совпадения, включающих все его внутренние подсовпадения. Чтобы указать такой способ поведения функции, передайте в качестве четвертого аргумента параметр PREG_SET_ORDER. Теперь three содержится не в элементе $matches, как раньше, а в элементе $matches.
Чтобы определить общее количество совпадений, проверьте значение, возвращенное функцией preg_match_all():
print preg_match_all("/(\w+)\s+potato\b/", $potatoes, $matches);
3
Обратите внимание, что совпадений только три, а не четыре, поскольку после слова four в строке нет завершающего слова potato.