Цикл в регулярном выражении. Как?

zuzu

Новичок
Цикл в регулярном выражении. Как?

Итак, есть туристический сайт, на котором очень много таблиц с ценами. Все таблицы разные и нестандартные. Необходимо сделать систему изменения цен менеджерами сайта. Что я придумал:
С помощью
PHP:
 preg_replace("!<td>(.*?)</td>!si","<td><textarea name="text[]">\\1</textarea><\td>",$string);
меняем каждую ячейку на <textarea> с содержимым ячейки. Затем уже измененное содержимое ячеек надо сохранить обратно. Тут и проблема. Я думаю так: опять ищем содержимое <td></td> и меняем его на содержимое переменной $text. Т.е.
PHP:
 preg_replace("!<td>(.*?)</td>!si","<td>$text<\td>",$string)
Вроде бы все правильно, но! $text - это массив, а нужна строка!
Можно подумать, что $text[$i] и есть строка, но как их перебрать в теле preg_replace????
 

WP

^_^
Задача элементарная.
PHP:
function callback_show($m)
{
 static $i = 0;
 return $m[1].'<textarea name="text['.$i.']">'.htmlspecialchars($m[2]).'</textarea>'.$m[3];
 $i++;
}
$text = preg_replace_callback('~(<td>)(.*?)(</td>)~si','callback_show',$string);
///////////////////

function callback_commit($m)
{
 static $i = 0;
 return $m[1].(isset($_REQUEST['text'][$i])?strval($_REQUEST['text'][$i]):'').$m[3];
 $i++;
}
$text = preg_replace_callback('~(<td>)(.*?)(</td>)~si','callback_commit',$string);
Писалось прям в Быстрый ответ, не запускал, поэтому может не пахать, но идея думаю ясна.


p.s. форум пробелы поле </td> поставил, их там нет.
 

sage

Новичок
Возврат приводит к завершению выполнения функции и передаче управления обратно к той строке кода, в которой данная функция была вызвана
PHP:
$i++;
выполняться не будет.
 

zuzu

Новичок
Большое спасибо! Я и не знал, что такая функция есть. Все понятно, но попробую позже.

-~{}~ 27.06.06 07:48:

Не работает:(
Непонятна вот эта строчка:
PHP:
return $m[1].(isset($_REQUEST['text'][$i])?strval($_REQUEST['text'][$i]):'').$m[3];
Зачем это: $_REQUEST['text'][$i] и знак вопроса?
Не работает даже, если написать в callback_commit
return $m[1].$text[$i].$m[3];
 

ThomLee

Новичок
Автор оригинала: SiMM
> Зачем ... знак вопроса?
[m]language.operators.comparison[/m]
На самом деле указанная выше конструкция несколько некорректна.
Код:
<?php
$a=1;
$b="test";
$test=$a.($a!=0)?"b":"a".$b;
echo $test;
?>
Вывод будет b
Не помню другие варианты записи, но сталкивался с этим. Но тут или обрежутся крайние значения, вокруг выражения (условие)?вариант:вариант;
или обрежется само условие.
Вот корректный пример:
Код:
<?php
$a=1;
$b="test";
$test=$a;
$test.=($a!=0)?"b":"a";
$test.=$b;
echo $test;
?>
Соответственно нужно переделать указанные выше функции.
Т.е. примерно так:
function callback_commit($m)
{
static $i = 0;
$ret=$m[1];
$ret.=(isset($_REQUEST['text'][$i])?strval($_REQUEST['text'][$i]):'').$m[3];
return $ret;
/*
Как вариант:
$m[1].=(isset($_REQUEST['text'][$i])?strval($_REQUEST['text'][$i]):'').$m[3];
если не хочется вводить новую переменную.
*/
$i++;
}
 

SiMM

Новичок
> На самом деле указанная выше конструкция несколько некорректна.
Голову напекло? Задача для первокласника на тему "найди два отличия":
1. $m[1].(isset($_REQUEST['text'][$i])?strval($_REQUEST['text'][$i]):'').$m[3]
2. $test=$a.($a!=0)?"b":"a".$b

> Не помню другие варианты записи, но сталкивался с этим. Но тут или обрежутся крайние значения, вокруг выражения (условие)?вариант:вариант; или обрежется само условие
Постить бредни на форуме не надо, надо просто пойти и наконец прочесть мануал - [m]language.operators#language.operators.precedence[/m]
 

WP

^_^
sage
Знаю =) Вслепую писал практически ибо футбол =)
ThomLee
Конструкция вполне корректна. Проверяем существует ли $_REQUEST['text'][$i], если существует, то приводим его значение к строковому типу и используем его, а если нет то пустую строку.
 

ThomLee

Новичок
Автор оригинала: WP
sage
Знаю =) Вслепую писал практически ибо футбол =)
ThomLee
Конструкция вполне корректна. Проверяем существует ли $_REQUEST['text'][$i], если существует, то приводим его значение к строковому типу и используем ег, а если нет то пустую строку.
млин, смотри внимательно:
$m[1].(isset($_REQUEST['text'][$i])?strval($_REQUEST['text'][$i]):'').$m[3]
вернет только результат (isset($_REQUEST['text'][$i])?strval($_REQUEST['text'][$i]):'').$m[3], конкатенацию $m[1] отрежет
поэтому запусать корректнее будет:

PHP:
$m[1].=(isset($_REQUEST['text'][$i])?strval($_REQUEST['text'][$i]):'').$m[3];
 

SiMM

Новичок
> понял где косяк?
Все уже давно всё поняли. Что у кого-то очень ПЛОХО со зрением и он считает, что
$test[0].(isset($test[1]))?$test[2]:$test[1];
и
$test[0].(isset($test[1])?$test[2]:$test[1]);
это одно и то же.
 

ThomLee

Новичок
Автор оригинала: SiMM
> понял где косяк?
Все уже давно всё поняли. Что у кого-то очень ПЛОХО со зрением и он считает, что
$test[0].(isset($test[1]))?$test[2]:$test[1];
и
$test[0].(isset($test[1])?$test[2]:$test[1]);
это одно и то же.
А, тьфу, сори. Сбило с толку большое кол-во скобок, глаза разбежались.
Надо было сразу пнуть в сторону, где не прав.
 

zuzu

Новичок
Ну и развели вы тут дискуссию:)))
sage прав! $i++ не работает ни в первой функции, ни во второй((((
Например в callback_show выводит во всех ячейках <textarea name="text[0]">. Получается, что перебор массива не происходит. $i все время сбрасывается на нуль.
 

ThomLee

Новичок
Как вариант устроит?
PHP:
<?php
$i=0;
function test($param,$i){//$i ссылка на переменную
          $i++;
     return $param.$i;
}

echo test("test",&$i);
?>
 

zuzu

Новичок
Короче, работает вот как
PHP:
function callback_commit($m) 
{ 
static $i = 0; 
$i++;
$ret=$m[1];
$ret.=(isset($_REQUEST['text'][$i])?strval($_REQUEST['text'][$i]):'').$m[3];
return $ret;
}
Т.е., если ставить $i++ перед, а не после. Почему именно так работает? не понятно...
ThomLee, спасибо, тоже вариант.
 

ThomLee

Новичок
гхм.. ну мы чайники, потому что после return стоит $i++
Соответсвенно значение возвращается и функция завершается, все действия после return игнорируются.
:)
 
Сверху