Я готов учится и могу заплатить. Но с наскока в такой функции я не могу разобраться. Допустим мне в одной переменной надо сделать 2 замены на 2 разных содержимых. Здесь Код (PHP): echo preg_replace_callback('/<\/p>/',function($m) use ($change) {static $i=0;return(3==++$i)?$change:$m[0];},$line); делается одна замена Нужно найти другой символ и заменить другим содержимым. Я сделал это в 2 прохода. И в принципе, с этим можно жить. Оно же работает. Но хочу понять, как это сделать компактнее. Начал искать использование OR в preg_replace_callback - не нашел. Отсюда возникает вопрос - это вообще возможно?
возможно. просто ты не программист и не можешь создать алгоритма. а нет алгоритма - нет понимания того какие инструменты надо использовать. что значит "OR в preg_replace_callback"?
Грубо говоря, если есть A, то заменяем на А1 ИЛИ если есть B, то заменяем на B1 Или использовать 2 массива - один с искомыми данными, второй с заменами. Но в таком случае, непонятно, как первую замену делать на 3-м вхождении, в вторую на 8-м. Я сделал коряво: Код (PHP): $text1="text1"; $text2="text2"; $firstreplace = preg_replace_callback('/<p>/',function($m) use ($text1) {static $i=0;return(3==++$i)?$text1:$m[0];},$adstext); $secondreplace = preg_replace_callback('/<p>/',function($m) use ($text2) {static $i=0;return(8==++$i)?$text2:$m[0];},$firstreplace); echo $secondreplace; Хочу сделать нормально.
Как я уже писал, надо в переменной найти 2 разных текста и заменить 2-мя разными заменами. Причем первую замену после 3-го вхождения, а вторую после 8-го. То есть, если в тексте 3 раза встречается "А", то третье вхождение заменяем на "A1" Дальше, если в тексте 8 раз встречается "B", то восьмое вхождение заменяем на "B1" Мы уже имеем код, делающий 1-ю замену Код (PHP): $text1="text1"; $firstreplace = preg_replace_callback('/<p>/',function($m) use ($text1) {static $i=0;return(3==++$i)?$text1:$m[0];},$adstext); Дальше, как я уже говорил, я вторую замену я сделал тупо 2-мя проходами Код (PHP): $text1="text1"; $text2="text2"; $firstreplace = preg_replace_callback('/<p>/',function($m) use ($text1) {static $i=0;return(3==++$i)?$text1:$m[0];},$adstext); $secondreplace = preg_replace_callback('/<p>/',function($m) use ($text2) {static $i=0;return(8==++$i)?$text2:$m[0];},$firstreplace); echo $secondreplace; Теперь, про 2 массива. Может будет правильно использовать 2 массива и делать замены одним проходом. Код (PHP): $massive1 = array("A", "B"); $massive2 = array("A1", "B1");
Не понимаю, как должен выглядеть такой массив. Добавлено спустя 16 секунд: Не понимаю, как должен выглядеть такой массив. Пример?
А второе искомое слово и вторая замена, по восьмому вхождению? И как эту конструкцию вставить в preg_replace_callback ? Конкретно сюда Код (PHP): $firstreplace = preg_replace_callback('/<p>/',function($m) use ($text1) {static $i=0;return(3==++$i)?$text1:$m[0];},$adstext);
Код (PHP): array( 'search' => array('replace', 2), 'search2' => array('replace2', 8), ); ну тема нынче в разделе где по желанию делают. у меня желания нет там всё очень просто. ключи упаковал как шаблон регулярки а в колбэке - сравнил с ключом, извлек метаниформацию, сравнил номер прохода, произвел замену. Добавлено спустя 37 минут 41 секунду: ой ладно, сейчас начнется нытье на тему того что если не хочешь помогать то вообще не пиши в тему противный и всё такое... Код (PHP): <?php // строка-жертва $str = <<<STR 1 aaa bbb ccc 2 aaa bbb ccc 3 aaa bbb ccc 4 aaa bbb ccc 5 aaa bbb ccc 6 aaa bbb ccc 7 aaa bbb ccc 8 aaa bbb ccc 9 aaa bbb ccc 10 aaa bbb ccc 11 aaa bbb ccc 12 aaa bbb ccc 13 aaa bbb ccc 14 aaa bbb ccc 15 aaa bbb ccc 16 aaa bbb ccc 17 aaa bbb ccc 18 aaa bbb ccc 19 aaa bbb ccc 0 aaa bbb ccc STR; // тот самый смешной массив искать-заменять $data = [ // что искать раз 'aaa'=> [ // на что заменять раз 'AaA', // заменять только второе вхождение 2, ], // что искать два 'bbb'=> [ // на что заменять два 'AbC', // замеять только третье вхождение 3, ], // что искать три 'ccc'=> [ // на что заменять три 'Defg', // заменять КАЖДОЕ пятое вхождение -5, ], ]; // создаем регулярное выражение (не скажу зачем отдельно вынес ибо это личное) $regex = '/' . implode('|', array_keys($data)) . '/'; // применяем замены к строке $str = preg_replace_callback($regex, function($m) use ($data) { // массив для счетчиков совпадений по искомым конструкциям static $counters = []; // массив регулярности замен static $regular = []; // если переданное в эм-ноль слово встретилось в массиве "искать-заменять"... if (isset($data[$m[0]])) { // ... решим что у нас с регулярностью ... if (!isset($regular[$m[0]])) { // если отричательное число - заменяем каждое ЭНное совпадение // иначе (6ля ну "если положительное число") - только конкретное совпадение $regular[$m[0]] = ($data[$m[0]][1] < 0); } // ... и проверим есть ли у нас счетчик для такого слова if (!isset($counters[$m[0]])) { // его нет - объявим $counters[$m[0]] = 0; } // ничего необычного - если N-ность совпадает с: // * заявленной положительным числом или // * регулярностью заявленной отрицательным числом // то ... $counters[$m[0]]++; if ( ($regular[$m[0]] && 0 == ($counters[$m[0]] % $data[$m[0]][1])) || ($counters[$m[0]] == $data[$m[0]][1]) ) { // ... производим замену return $data[$m[0]][0]; } } // иначе положим на место что брали return $m[0]; }, $str); // насладимся результатом var_dump($str); // скажем спасибо человеку за пару минут потраченного времени echo 'Spasibo, Ganzal!!!', "\n"; // eof Код (PHP): string(293) "1 aaa bbb ccc 2 AaA bbb ccc 3 aaa AbC ccc 4 aaa bbb ccc 5 aaa bbb Defg 6 aaa bbb ccc 7 aaa bbb ccc 8 aaa bbb ccc 9 aaa bbb ccc 10 aaa bbb Defg 11 aaa bbb ccc 12 aaa bbb ccc 13 aaa bbb ccc 14 aaa bbb ccc 15 aaa bbb Defg 16 aaa bbb ccc 17 aaa bbb ccc 18 aaa bbb ccc 19 aaa bbb ccc 0 aaa bbb Defg" Spasibo, Ganzal!!! воркс лайк э шарм.
Все равно у них не верное условие..., оно не будет работать правильно, там на неравенство нужно условие, а не на равенство. Код (PHP): function text($str, $search = '', $replace = '', $pos = 0) { if (!$str || !$search || !$replace || !$pos) { return; } $search = preg_quote($search); return preg_replace_callback("/{$search}/iu", function($matches) use($pos, $replace) { static $i = 0; if ($pos !== ++$i) { return $matches[0]; } return $replace; }, $str); } Теперь отрабатывает верно. Код (PHP): echo text('Текст, тЕкст, ТЕКст', 'Текст', '2 текст', 2); //Текст, 2 текст, ТЕКст Если в позицию писать 1 или 2 или 3, он правильно будет заменять текст.
preg_replace_callback, function, use... извращенцы Код (PHP): $s = 'бе бе 123 123 123 123 abc abc abc abc'; var_dump(preg_replace(['/(.*2.*2.*)(2)/U', '/(.*b.*b.*b.*)(b)/U'], ['${1}0', '${1}B'], $s));
Chushkin, один из первых моих начальников (там просто начальников много было) очень любил повторять две фразы: "крутая техника в руках идиотов - кусок пластмассы" (но сейчас не об этом) и "профессионализм не в знании инструмента, а в умении его применять". ты очень элегантно применил одну единственную функцию. просто браво!
Увидев твой вариант, мне показался он немного пугающим, тем, что нужно составлять регулярки всегда и квотить их, однако это будет правильнее, но сложнее и времени нужно больше, чтобы, что - то действительное стоящее вышло. Но вышло довольно элегантно. Просветил)
Все же, удобнее будет 1, 2, 3, более естественно выглядит, а остальное ты уже дал. Хоть и как вариант вообще еще лучше заюзать и в правду регулярками