preg_replace (), вызываемый с массивами, требует ksort () заранее? А? - PullRequest
2 голосов
/ 21 декабря 2009

Я немного работал с preg_replace в выходные и читал документацию Php preg_replace , когда увидел что-то странное

Пример # 2 из документов показывает, что при наличии следующего php-кода

<?php
$string = 'The quick brown fox jumped over the lazy dog.';
$patterns[0] = '/quick/';
$patterns[1] = '/brown/';
$patterns[2] = '/fox/';
$replacements[2] = 'bear';
$replacements[1] = 'black';
$replacements[0] = 'slow';
echo preg_replace($patterns, $replacements, $string);
?>

вывод будет

"The bear black slow jumped over the lazy dog."

и для генерации того, что (на мой взгляд) должно выводиться по умолчанию, мне нужно было бы предварительно вызвать ksort(). как это:

<?php
ksort($patterns);
ksort($replacements);
echo preg_replace($patterns, $replacements, $string);
?>

Разве это не обходной путь для ошибки в preg_replace() php? Почему php ведет себя так? Есть ли какая-то особенность с объявленными здесь массивами, которые мне не хватает?

Ответы [ 4 ]

4 голосов
/ 21 декабря 2009

документы также говорят:

ключи обрабатываются в порядке их появления в массиве

Так что причина этого в том, что используется простая итерация типа foreach, а не доступ по индексу.

2 голосов
/ 21 декабря 2009

К сожалению, все массивы в PHP являются ассоциативными массивами.

$replacements[2] = 'bear';
$replacements[1] = 'black';
$replacements[0] = 'slow';

Хранится как 2 -> медведь, 1 -> черный, 0 -> медленный

Вместо типичных блоков

медленно | черный | несут

1 голос
/ 21 декабря 2009

Индексы массива - это просто то, что индексы не определяют, где в памяти хранятся значения, функции вроде next () и current (), которые, как мне кажется, preg_replace использует при передаче массивов, перебирает массив из начальной памяти обратитесь к последнему за оперативностью.

Как и многие другие вещи в php, эта итерация массива построена для скорости, все остальное вполне справедливо для разработчика, поэтому вам нужно добавить еще пару строк, чтобы выполнить немного больше работы.

0 голосов
/ 21 декабря 2009

preg_replace() ведет себя так, как если бы он выполнял код, подобный этому

reset($patterns);
reset($replacements);

$pattern = current($patterns);
$replacement = current($replacements);

do {
  // Replace the pattern, if found.
  $pattern = next($patterns);
  $replacement = next($replacements);
} while ($pattern !== FALSE);

Я бы предпочел, чтобы функция работала без вызова ksort().

...