Замена n-го элемента в php (регулярное выражение)

12
djdiplomat
На сайте с 05.08.2009
Offline
136
4999

Люди! Изучаю реги. Возник вопрос.

Вот к примеру есть строка:

"Привет Марина, Привет Марина, Привет Марина, Привет Марина"

Как используя регулярное выражение заменить второе слово "Привет" на "Здравствуй"

Так меняет глобально (все четыре привета заменяет):

$text = "Привет Марина, Привет Марина,  Привет Марина, Привет Марина";
$text = preg_replace ('/Привет/','Здравствуй',$text);

Вообще, как заставить ф-ю preg_replace заменять не все совпадения, а лишь какое-то определенное?

Милованов Ю.С
На сайте с 24.01.2008
Offline
196
#1

Да никак(или я что-то в этой жизни проспал), если конечно явно не указать.

preg_replace ('/12,12,12,12/', '12,34,12,12', $text);

Подпись))
djdiplomat
На сайте с 05.08.2009
Offline
136
#2

Не, я точно знаю, что алгоритм какой-то есть.

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

Может, правда, это не через preg_replace делается, а как-то через другую ф-ю, но что такое есть, я знаю. Хотелось бы узнать хоть какое-нибудь глобальное решение.... =)

Для PERL же есть =) ( http://www.opennet.ru/base/dev/perl_regexp_n.txt.html )

Значит для php тоже должно быть.

IL
На сайте с 20.04.2007
Offline
435
#3
djdiplomat:
Вообще, как заставить ф-ю preg_replace заменять не все совпадения, а лишь какое-то определенное?

djdiplomat, принципиально именно preg_replace?

А разбить при помощи preg_match, заменить нужный и потом склеить - не?

Первое

$text = preg_replace ('/Привет/','Здравствуй',$text,1);

Конкретно "второе" вхождение в данном случае можно заменить так:

$text = preg_replace ('/(.)Привет/','\1Здравствуй',$text,1);

p.s. при помощи preg_replace_callback "что угодно" можно сделать..

... :) Облачные серверы от RegRu - промокод 3F85-3D10-806D-7224 ( http://levik.info/regru )
Милованов Ю.С
На сайте с 24.01.2008
Offline
196
#4

Ну там тоже явное указание: первый и второй номер не меняем, а третий заменяем на 9-9999.

djdiplomat
На сайте с 05.08.2009
Offline
136
#5
ivan-lev:
djdiplomat, принципиально именно preg_replace?
А разбить при помощи preg_match, заменить нужный и потом склеить - не?

p.s. при помощи preg_replace_callback "что угодно" можно сделать..

Не. ну а если у меня к примеру 10 000 слов. В которых порядка 150 одинаковых и мне нужно заменить к примеру с 20-50 и далее через один. Склейка мне явно не катит...

Комп заманается резать и клеить

PS а можно расшифровать эту запись:

$text = preg_replace ('/(.)Привет/','\1Здравствуй',$text,1);

Я как понял.

/(.)Привет/ - поиск "привет" у которого впереди любой знак

\1Здравствуй - вот тут я не вкурил в экранированную единичку. Это указатель на элемент массива? (типа цифра 1 - значит 2-й элемент т.к у массива все начинается с 0) ?

И после запятой ext,1); - это что за зверь? (количество подряд идущих замен?)

Dreammaker
На сайте с 20.04.2006
Offline
569
#6
djdiplomat:
Для PERL же есть =) ( http://www.opennet.ru/base/dev/perl_regexp_n.txt.html )

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

---------- Добавлено 01.04.2013 в 09:51 ----------

djdiplomat:
Комп заманается резать и клеить

меняйте комп, если с такими слабыми задачами не справляется :)

IL
На сайте с 20.04.2007
Offline
435
#7
Dreammaker:
а это значит и в пхп вы тоже можете использовать условия в регулярках. То, есть по смыслу это не должно отличаться от описанного в той статье для перла.

не-не.. отличия есть... но тем не менее модификатор e (PREG_REPLACE_EVAL) работает и в PHP..


$counter = 0;
$text = "Привет Марина, Привет Марина, Привет Марина, Привет Марина";
$text = preg_replace ('/Привет/ie',"\$counter++==1?'Здравствуй':'\\0'",$text);

echo $text;
djdiplomat:
Не. ну а если у меня к примеру 10 000 слов. В которых порядка 150 одинаковых и мне нужно заменить к примеру с 20-50 и далее через один. Склейка мне явно не катит...

Да всё катит.. Если есть возможность, на больших объёмах вместо регулярок, я бы лучше "обычные" строковые (см str_replace) функции использовал.. На реальных 10к данных можете провести тесты и выложить результаты.. и по быстродействию, и по памяти..

---------- Post added 01-04-2013 at 11:10 ----------

djdiplomat:
И после запятой ext,1); - это что за зверь? (количество подряд идущих замен?)
djdiplomat:
Люди! Изучаю реги. Возник вопрос.

А изучение не подразумевает в ман заглянуть?


mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )


Список параметров ...
sabotage
На сайте с 14.02.2007
Offline
192
#8
djdiplomat:
Вообще, как заставить ф-ю preg_replace заменять не все совпадения, а лишь какое-то определенное?

http://php.net/manual/ru/function.preg-replace.php

int $limit

IL
На сайте с 20.04.2007
Offline
435
#9
sabotage:
http://php.net/manual/ru/function.preg-replace.php
int $limit

Это, если первые сколько-то нужно.. Не, можно конечно туда-сюда менять.. :)

ivan-lev:
модификатор e (PREG_REPLACE_EVAL) работает и в PHP..

Там, кстати, примечания есть для модификатора.. имеет смысл обратить внимание

djdiplomat
На сайте с 05.08.2009
Offline
136
#10

Спасибо всем.

В ман я конечно, заглянул (просто изначально не внимательно прочел).

Правда, что-то пока в это дело

$text = preg_replace ('/Привет/ie',"\$counter++==1?'Здравствуй':'\\0'",$text);

(жирным пометил) не вкурил...

12

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий