php, preg_replace

Vodnik

можно как нибудь (указать модификатор и тп) чтобы замена проводилась не один раз, а столько сколько возможно?

tihon972009

По моему, она и должна проводиться столько раз, сколько возможно.
Ботай
http://ru.php.net/manual/en/
http://ru.php.net/manual/ru/
То же в виде html-файлов:

Ilya1974

http://php.net/preg_replace:
limit
The maximum possible replacements for each pattern in each subject string. Defaults to -1 (no limit).

kruzer25

Думаю, автор тут имеет в виду, чтобы при preg_replace("/11/","1",$str) мы из строки, состоящей из единиц, получили только одну единицу.
Я делал это так:
function my_preg_replace($pattern,$replacement,$string) {
$tmp2=$string;
$tmp1='';
while($tmp2!=$tmp1) {
$tmp1=$tmp2;
$tmp2=preg_replace($pattern,$replacement,$tmp1);
}
return $tmp2;
}
Работает, конечно, не только со строками - с массивами тоже.

Ilya1974


function my_preg_replace( $pattern, $replacement, $string )
{
$count = 0;
do
{
$string = preg_replace( $pattern, $replacement, $string, -1, count );
} while ( $count );
return $string;
}

kruzer25

Выглядит менее очевидно.

Ilya1974

Ест в три раза меньше памяти под переменные. Использует встроенный механизм для проверки того, были ли замены. И выглядит, кстати, более очевидно, на мой взгляд. У тебя можно запутаться в $tmp2 = $tmp1.
Правда, работает только в PHP5.

kruzer25

И выглядит, кстати, более очевидно, на мой взгляд
1) "Строка изменилась" - более очевидно, чем "было сделано 0 замен".
2) Мой метод подходит абсолютно для всех функций, модифицирующих строку. Не только для preg_replace в PHP >=5 - для всего.

Ilya1974

Ну отлично ведь!

kruzer25

Что отлично?
Что ты сэкономишь две длины строки в оперативной памяти?

Ilya1974

У меня код очень красивый. Я сидел минуту любовался после написания.
А так - и у тебя хорошо, и у меня хорошо, зачем спорить.

kruzer25

Если ты любовался - то как не заметил в нём ошибку?

Ilya1974

Зачем? При первом же прогоне исправлю. Главное, что идея правильная, доллар можно и забыть где-нибудь.

kruzer25

А пока что полюбуешься, какой у тебя красивый и нерабочий код получился?

sakura

не знаю как в в php, но в perl есть модификатор g, который делает то, что тебе нужно, например:
$str = "abababab";
$str =~ s/b/A/;
# Here $str = "aAababab"
$str =~ s/b/A/g;
# Here $str = "aAaAaAaA"

Ilya1974

Это рабочий код, там просто забыт $.

Ilya1974

Более того, он будет работать даже и в таком виде с notice'ом, что непонятно, что это за count, использую как я $count.

kruzer25

Чуве, ты не понял суть проблемы, в php этот модификатор используется по умолчанию.
Автору нужно, судя по всему (и мы говорим именно об этом как регулярным выражением ~s/aa/a/ преобразовать строку, состоящую из миллиона букв "a", в строку, состоящую из одной буквы a.
Твои же выражения в первом случае дают строку из 999999 букв "а", во втором - из 500000 букв "а".

Ilya1974

Не то.
Пенартур хочет, чтобы регексп прогонялся до тех пор, пока он срабатывает, а не чтобы везде менял.

kruzer25

Это с какими настройками?
Он выдаст notice, что не знает константу count, и передаст preg_replace'у строку 'count'.
Что, естественно, даст тебе бесконечный цикл.
UPD: Ошибся, не бесконечный - простозамена произведётся только один раз.

Ilya1974

Хз, у меня нет php5, не могу проверить.
Но скорее всего, все будет еще хуже. count - это же функция, то есть может, по идее, попросить аргументы к ней. Не знаю, я не силен в php на уровне "доебаться к собеседнику".
Главное, что я за один-два прогона этот код сделаю рабочим, даже если там какой-то символ пропущен.

sakura

Автору нужно, судя по всему (и мы говорим именно об этом как регулярным выражением ~s/aa/a/ преобразовать строку, состоящую из миллиона букв "a", в строку, состоящую из одной буквы a.
ну это же еще проще в перле:
$str = 'aaaaaaaaaaaaaaaaBBBaaaaaaaaaaaaaa';
$str =~ s/a+/a/g;
#Here $str = 'aBBBa'
Или это тоже не то, что нужно?

kruzer25

Поздравляю, ты решил частный случай!
Я говрол не о конкретных буквах "а", а о том, что хочется заменять, пока заменяется.
Вот представь себе замену:
$str=preg_replace("/^(\d\d+)$/e","\\1+\\2",$str)
Если хочется из строки, представляющей число, получить строку, представляющую остаток от деления этого числа на 9.
Конечно, ты и на этот частный случай можешь придумать свой особый метод.
А вот в этих двух случаях ты видишь что-нибудь общее?

Andbar

Более того, он будет работать даже и в таком виде с notice'ом, что непонятно, что это за count, использую как я $count.
интересно.... В ПХП4 при появлении count без доллара, она заменяется на строку 'count'. В том случае, если функция preg_replace (забудем на минуту о том, что она делает и какие у неё параметры) не воспринимает последний аргумент или не требует там переменной, твоя функция прогонит preg_replace ОДИН раз, при чем ты получишь нотайс о преобразовании count в 'count'... Не особо грозный нотайс. Если бы ты не написал $count = 0; , вылетел бы более (имхо) грозный нотайс - неопределённая переменная.
Хотя, впрочем, без строчки $count = 0; и с поправленным вызовом функции, твой код более красивый, опять-же имхо.

Ilya1974

Как это - без строчки?
Мне же нужно объявить $count заранее.

Vodnik

thnx, именно это я имел ввиду

Andbar

Мне же нужно объявить $count заранее.
Ну так ты объявляй её прямо при вызове функции... Переменную можно объявить везде, где ей задаётся значение. А смысла задавать значение, которое гарантированно перезапишется не вижу.
Впрочем, разговор, имхо, теряет смысл... Почему-то на php.net нету никакого указание на дополнительный параметр.
http://ru.php.net/manual/ru/function.preg-replace.php

kruzer25

Не успели перевести, значит.
http://ru.php.net/manual/en/function.preg-replace.php

Flack_bfsp

Офигеть. А я-то думал, что русско-английский мануал такой же, как и английский. И часто там такое несовпадение?

kruzer25

ChangeLog
Version Description
4.0.1pl2 Added the limit parameter
4.0.4 Added the '$n' form for the replacement parameter
5.1.0 Added the count parameter
Видимо, нечасто - 5.1.0 вышел не так давно, а в русском переводе, судя по всему, просто осталась старая версия.
Оставить комментарий
Имя или ник:
Комментарий: