[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: preg_replace и замена из массива
Sirian
Добрый день.

интересует такой вопрос.
предположим есть строка
{odin}, {dva}, {tri}

и есть некий массив

$arr = array('odin' => 1, 'dva' => 2, 'tri' => 3, ...);


мне нужно заменить в строке {odin} на 1, {dva} на 2 и т.п.
т.е. получаться должна строка вида...
1 2 3


как лучше всего это произвести?
цикл по индексам - не самое хорошее решение, т.к. в массиве может быть ооооочень много индексов, и для каждого делать str_replace - не вариант.
а такое:
preg_replace('~\{([a-z]+)\}~e', $arr["\\1"], $str);

не работает почему-то



Спустя 9 часов, 35 минут, 36 секунд (10.01.2010 - 23:35) kirik написал(а):
Цитата (Sirian @ 10.01.2010 - 05:59)
для каждого делать str_replace - не вариант

Зачем для каждого? str_replace нормально с массивами работает. Тем более строковые функции намного быстрее регулярок.

Спустя 1 день, 15 часов, 29 минут, 43 секунды (12.01.2010 - 15:05) Guest написал(а):
проблема в том, что мне надо заменить не odin на 1, а {odin} на 1

Спустя 1 час, 11 минут, 34 секунды (12.01.2010 - 16:16) stepan написал(а):
Цитата (Guest @ 12.01.2010 - 12:05)
проблема в том, что мне надо заменить не odin на 1, а {odin} на 1

и в чем же здесь сложность?
foreach ( $arr as $name => $value )
{
str_replace ( '{' . $name . '}', $value, $str );
}

Спустя 1 час, 1 минута, 11 секунд (12.01.2010 - 17:17) Guest написал(а):
повторяю еще раз первый пост:
цикл по индексам - не самое хорошее решение, т.к. в массиве может быть ооооочень много индексов, и для каждого делать str_replace - не вариант.

Спустя 54 минуты, 37 секунд (12.01.2010 - 18:12) Guest написал(а):
ну в общем сам решил свой вопрос....
задача немного расширенная. заменить не {odin} на 1. а языковые подстановки делать.
например строка
{lng:some_key}

$arr = array('some_key' => 'some_text');

вот моя функция (член класса, поэтому $this->tpl там)
function set_array($name, $array)
{
$length = strlen($this->tpl);
$offset = 0;
$find = '{' . $name . ':';
$findlen = strlen($find);
$result = '';
$index = '';
while (1)
{
$pos = strpos($this->tpl, $find, $offset);
if ($pos !== false)
{
$result .= substr($this->tpl, $offset, $pos - $offset);
$i = $pos + $findlen;
$index = '';
$arr = array();
while (1)
{
if ($i >= $length)
break;
if ($this->tpl[$i] == '}')
{
$arr[] = $index;
break;
}elseif ($this->tpl[$i] == ':')
{
$arr[] = $index;
}else
$index .= $this->tpl[$i];
$i++;
}
switch (count($arr))
{
case 1:
$result .= $array[$arr[0]];
break;
case 2:
$result .= $array[$arr[0]][$arr[1]];
break;
case 3:
$result .= $array[$arr[0]][$arr[1]][$arr[2]];
break;
default:
}
$offset = $i+1;
}else{
$result .= substr($this->tpl, $offset, $length - $offset);
break;
}

}

$this->tpl = $result;
}

Спустя 2 минуты, 17 секунд (12.01.2010 - 18:14) Guest написал(а):
ах да... также бывает нужно сделать сложную подстановку:
например
{lng:array_month:january}

и
$arr = array('array_month' => array('january' => 'Январь'))


поэтому в функции стоит соответствующий switch (рассчитан на тройную вложенность). Как показывает практика - больше не надо

Спустя 17 минут, 23 секунды (12.01.2010 - 18:32) Guest написал(а):
небольшая поправка:

}elseif ($this->tpl[$i] == ':')
{
$arr[] = $index;

заменить на

}elseif ($this->tpl[$i] == ':')
{
$arr[] = $index;
$index = '';
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2025 Invision Power Services, Inc.