Поиск и замена
Существует несколько различных функций / методов для замены определенной части строки чем-то другим, все со своими преимуществами.
str_replace()
метод (двоичный сейф; чувствителен к регистру)
Аргументы
смешанный str_replace (смешанный $ поиск , смешанный $ replace , смешанный $ subject [, int & $ count])
str_replace()
имеет 3 обязательных аргумента, как вы можете видеть в приведенном выше определении в правильном порядке, каждый из которых может принимать строку в качестве аргумента и массив!
Поиск и замена
поиск (строка) И замена (строка) → Заменяет строку поиска на строку замены.
поиск (массив) И замена (строка) → Замена всех элементов поиска строкой замены.
поиск (строка) И замена (массив) → Выдает уведомление: «Примечание: преобразование массива в строку», потому что замена массива только для одной строки поиска не имеет смысла, поэтому пытается преобразовать массив в строку.
поиск (массив) И замена (массив) → Заменяет каждый элемент поиска соответствующим элементом замены(Ключи игнорируются!).
поиск (больше элементов) И замена (меньше элементов) → Заменяет каждый элемент поиска соответствующимзаменить элемент (для отсутствующих элементов замены будет использоваться пустая строка).
поиск (меньше элементов) И замена (больше элементов) → Заменяет каждый элемент поиска соответствующим элементом замены (ненужные элементы замены игнорируются).
Тема
Код
echo str_replace("search", "replace", "text search text");
echo str_replace(["t", "a"], "X", "text search text");
echo str_replace("search", ["replace1", "replace2"], "text search text");
echo str_replace(["a", "c"], ["X", "Y"], "text search text");
Output
text replace text
XexX seXrch XexX
Notice: Array to string conversion
text seXrYh text
Примечания
Понятно!
Важно знать, что str_replace()
работает сслева направо от массива.Это означает, что он может заменить значение, которое вы уже заменили.Например:
echo str_replace(array("a", "b"), array("b", "c"), "aabb");
//Probably expected output: bbcc
//Actual output: cccc
Без учета регистра
Если вы хотите сделать поиск без учета регистра, вы можете использовать str_ireplace()
(Обратите внимание наi
для регистра - i нечувствителен).
Многомерный массив
str_replace()
/ str_ireplace()
НЕ работает для многомерных массивов.См. Этот ручной комментарий для такой реализации.Конечно, вы также можете заменить str_replace()
на str_ireplace()
без учета регистра.
Если вы хотите собрать все воедино и создать функцию, которая также работает для многомерных массивов без учета регистраВы можете сделать что-то вроде этого:
<?php
function str_ireplace_deep($search, $replace, $subject)
{
if (is_array($subject))
{
foreach($subject as &$oneSubject)
$oneSubject = str_ireplace_deep($search, $replace, $oneSubject);
unset($oneSubject);
return $subject;
} else {
return str_ireplace($search, $replace, $subject);
}
}
?>
strtr()
метод (50% бинарный безопасный; чувствителен к регистру)
Аргументы
строка strtr (строка $ str , строка $ от , строка $ до )
строка strtr (строка $ str , массив $ replace_pairs )
Функция принимает либо 3 аргумента со строкой from и to, либо 2 аргумента с массивом замены array("search" => "replace" /* , ... */)
,все это вы можете увидеть в приведенном выше определении в правильном порядке.
2 Аргументы
Запускаетсязаменить самый длинный ключ соответствующим значением и делать это до тех пор, пока он не заменит все пары key => value
В этом случае функция является бинарно-безопасной, поскольку использует весь ключ / значение.
3 Аргументы
Он заменяет аргумент from на аргумент to в теме byte byte . Так что это не бинарный сейф!
Если аргументы from и to имеют неодинаковую длину, замена прекращается, когда она достигает конца более короткой строки.
Тема
Он не принимает массив как тему, только строку.
Код
echo strtr("text search text", "ax", "XY");;
echo strtr("text search text", ["search" => "replace"]);
выход
teYt seXrch teYt
text replace text
Примечания
Попался!
В отличие от str_replace()
, strtr()
НЕ заменяет что-либо дважды. Как пример:
echo strtr("aabb", ["a" => "b", "b" => "c"]);
//Expected output: bbcc
//Actual output: bbcc
Также, если вы хотите заменить несколько вещей одной строкой, вы можете использовать array_fill_keys()
, чтобы заполнить массив замены значением.
Без учета регистра
strtr()
НЕ является регистронезависимым NOR, есть ли регистрозависимая эквивалентная функция. См. Этот ручной комментарий для реализации без учета регистра.
Многомерный массив
strtr()
против str_replace()
НЕ работает с массивами в качестве субъекта, поэтому он также НЕ работает с многомерными массивами. Конечно, вы можете использовать приведенный выше код из str_replace()
для многомерных массивов и просто использовать его с strtr()
или реализацией stritr()
.
Если вы хотите собрать все воедино и создать функцию, которая также работает для многомерных массивов без учета регистра, вы можете сделать что-то вроде этого:
<?php
if(!function_exists("stritr")){
function stritr($string, $one = NULL, $two = NULL){
/*
stritr - case insensitive version of strtr
Author: Alexander Peev
Posted in PHP.NET
*/
if( is_string( $one ) ){
$two = strval( $two );
$one = substr( $one, 0, min( strlen($one), strlen($two) ) );
$two = substr( $two, 0, min( strlen($one), strlen($two) ) );
$product = strtr( $string, ( strtoupper($one) . strtolower($one) ), ( $two . $two ) );
return $product;
}
else if( is_array( $one ) ){
$pos1 = 0;
$product = $string;
while( count( $one ) > 0 ){
$positions = array();
foreach( $one as $from => $to ){
if( ( $pos2 = stripos( $product, $from, $pos1 ) ) === FALSE ){
unset( $one[ $from ] );
}
else{
$positions[ $from ] = $pos2;
}
}
if( count( $one ) <= 0 )break;
$winner = min( $positions );
$key = array_search( $winner, $positions );
$product = ( substr( $product, 0, $winner ) . $one[$key] . substr( $product, ( $winner + strlen($key) ) ) );
$pos1 = ( $winner + strlen( $one[$key] ) );
}
return $product;
}
else{
return $string;
}
}/* endfunction stritr */
}/* endfunction exists stritr */
function stritr_deep($string, $one = NULL, $two = NULL){
if (is_array($string))
{
foreach($string as &$oneSubject)
$oneSubject = stritr($string, $one, $two);
unset($oneSubject);
return $string;
} else {
return stritr($string, $one, $two);
}
}
?>
preg_replace()
метод (двоичный код, чувствительный к регистру)
Аргументы
смешанный preg_replace (смешанный $ шаблон , смешанный $ замена , смешанный $ субъект [, int $ limit = -1 [, int & $ count] ])
preg_replace()
имеет 3 обязательных параметра в указанном выше порядке. Теперь все 3 из них могут принимать строку в качестве аргумента и массив!
Поиск и замена
поиск (строка) И замена (строка) → Заменяет все совпадения регулярного выражения поиска на строку замены.
поиск (массив) И замена (строка) → Заменяет все совпадения каждого регулярного выражения поиска на строку замены.
поиск (строка) И замена (массив) → Выдает предупреждение: «Предупреждение: preg_replace (): Несоответствие параметра, шаблон - строка, а замена - массив ", потому что замена массива только для одного поискового регулярного выражения не имеет смысла.
поиск (массив) И замена (массив) → Заменяет все совпадения каждого регулярного выражения поиска на соответствующий элемент замены (ключи игнорируются!).
поиск (больше элементов) И заменить (меньше элементов) → Заменяет все совпадения каждого регулярного выражения поиска на соответствующий элемент замены (для отсутствующих элементов замены пустой будет использоваться строка).
поиск (меньше элементов) И заменить (больше элементов) → Заменяет все совпадения каждого регулярного выражения поиска на соответствующий элемент замены (ненужные элементы замены игнорируются).
Тема
Пожалуйста, неЕще раз: поиск должен быть регулярным выражением!Это означает, что ему нужны разделители и специальные символы должны быть экранированы.
Код
echo preg_replace("/search/", "replace", "text search text");
echo preg_replace(["/t/", "/a/"], "X", "text search text");
echo preg_replace("/search/", ["replace1", "replace2"], "text search text");
echo preg_replace(["a", "c"], ["X", "Y"], "text search text");
Выход
text replace text
XexX seXrch XexX
Warning: preg_replace(): Parameter mismatch, pattern is a string while replacement is an array
text seXrYh text
Примечания
Понятно!
То же, что str_replace()
, preg_replace()
работает слева направо массива.Это означает, что он может заменить значение, которое вы уже заменили.Например:
echo preg_replace(["/a/", "/b/"], ["b", "c"], "aabb");
//Probably expected output: bbcc
//Actual output: cccc
Без учета регистра
Поскольку аргумент поиска является регулярным выражением, вы можете просто передать flag i
для регистранечувствительный поиск.
многомерный массив
preg_replace()
НЕ работает для многомерных массивов.
обратная ссылка
Имейте в виду, что вы можете использовать \\n
/ $n
в качестве обратной ссылки на группы захвата регулярного выражения.Где 0
- это полное совпадение, а 1-99
- для групп захвата.
Кроме того, если после обратной ссылки сразу следует число, вы должны использовать \${n}
.
Замена / "Модификатор / e устарел"
Замена в preg_replace()
не может использовать функции обратного вызова в качестве замены.Так что вы должны использовать preg_replace_callback()
.То же самое, когда вы используете модификатор e
и получаете "Deprecated: preg_replace (): модификатор / e устарел, вместо этого используйте preg_replace_callback".См .: Замените preg_replace () e модификатор на preg_replace_callback
Если вы хотите собрать все вместе и создать функцию, которая также работает для многомерных массивов без учета регистра, вы можетесделать что-то вроде этого:
<?php
function preg_replace_deep($search, $replace, $subject)
{
if (is_array($subject))
{
foreach($subject as &$oneSubject)
$oneSubject = preg_replace_deep($search, $replace, $oneSubject);
unset($oneSubject);
return $subject;
} else {
return preg_replace($search, $replace, $subject);
}
}
?>
Петли while
/ for
/ foreach
метод (НЕ бинарный безопасный; чувствителен к регистру)
Теперь, конечно, помимо всех этих функций, вы также можете использовать простой цикл для циклического перебора строки и замены каждой пары search => replace
, которая у вас есть.
Но это становится намного сложнее, когда вы делаете это двоично-безопасно, без учета регистра и для многомерных массивов, чем просто используя функции выше.Поэтому я не буду приводить здесь примеры.
Затронутая строка
Сейчас все методы, показанные выше, выполняют замену всей строки.Но иногда вы хотите заменить что-то только для определенной части вашей строки.
Для этого вы, вероятно, захотите / можете использовать substr_replace()
.Или другой распространенный метод - использовать substr()
и применять замену только к этой конкретной подстроке, а затем соединять строку.Конечно, вы также можете изменить свое регулярное выражение или сделать что-то еще, чтобы не применять замену ко всей строке.