Учитывая строку с одной или несколькими строками поиска, разделенными пробелом, я хотел бы искать совпадения в тексте без учета регистра. Когда совпадение найдено, я хочу добавить <- сразу после совпавшей подстроки.
Вот что я пробовал:
Код
public function my_replace(string $fullText, string $searchText){
$searches = explode(' ',$searchText);
$replace = array();
foreach ($searches as $i => $search){
$replace[] = $search . '<-';
}
return str_ireplace($searches, $replace, $fullText);
}
Пример
echo my_replace('A week ago, Elvis left the Building', 'elvis left');
Выход
A week ago, elvis<- left<- the Building
Желаемый результат
A week ago, Elvis<- left<- the Building
Итак, я хочу заменить либо Elvis, либо elvis, следовательно, str_ireplace, но на выходе я хочу показать его так же, как это было раньше.
tldr;
Как заменить строку на тот же регистр, если заменяемая строка на самом деле отличается от регистра? Это вообще имеет смысл?






Замена строки просто заменит то, что вы ей предоставили, поэтому strireplace, вероятно, не будет работать так, как вы ожидаете в вашем случае.
В вашем конкретном случае использования вы можете вместо этого вручную искать каждое из ваших текстовых слов на предмет совпадений поиска без учета регистра и обновлять текст, как показано ниже:
function my_replace(string $fullText, string $searchText){
$searches = explode(' ',$searchText);
$fullText = explode(' ', $fullText);
$result = [];
foreach ($fullText as $word) {
$found = array_filter($searches, function ($search) use ($word) {
return strcasecmp($word, $search) === 0;
}); //If the array is not empty then $found is truthy otherwise its falsey
$result[] = $word.($found ? "<-" : "");
}
return implode(" ", $result);
}
echo my_replace('A week ago, Elvis left the Building', 'elvis left');
Это будет эхом:
A week ago, Elvis<- left<- the Building
Пример: http://sandbox.onlinephpfunctions.com/code/3139650b0af1fa30712d05f2453b30b3cf66d5e1
Я внес некоторые изменения в ваш код,
Этот preg_replace поможет вам в решении ваших проблем,
Фрагмент
function my_replace(string $fullText, string $searchText)
{
$searches = explode(' ', $searchText);
$replace = array();
foreach ($searches as $i => $search) {
$fullText = preg_replace("/$search/i", "\$0<-", $fullText);
}
return $fullText;
}
echo my_replace('A week ago, Elvis left the Building', 'elvis left');
Вот рабочий демонстрация.
Программный вывод
A week ago, Elvis<- left<- the Building
Я рекомендую один вызов preg_replace() с конвейерными строками поиска, границами слов для точности и флагом без учета регистра.
Код: (Демо)
function my_replace (string $fullText, string $searchText) {
$searches = str_replace(' ', '|', $searchText);
return preg_replace("/\b(?:$searches)\b\K/i", "<-", $fullText);
}
echo my_replace('A week ago, Elvis left the Building', 'elvis left');
Выход:
A week ago, Elvis<- left<- the Building
\K перезапускает полное совпадение строки. Таким образом, я говорю preg_replace(), чтобы он забыл весь матч, но запомнил конечную позицию - вот куда идет <-.
Прелесть в том, что нет повторных вызовов функций. Все это делается за один проход.
p.s. если ваши поисковые строки исходят от пользователей или других ненадежных источников, используйте preg_quote() для защиты шаблона регулярного выражения с помощью экранирования.
$searches = str_replace(' ', '|', preg_quote($searchText, "/"));
@PrimuS Я отправляю запоздалые ответы, когда могу предоставить превосходный фрагмент.
Кажется, вам нравится вставлять '<-' после искомого слова, даже если регистр не тот, может быть, вы можете использовать любое из следующих действий: -
используя preg_match_all и preg_replace -
function my_replace(string $fullText, string $searchText){
$searches = explode(' ',$searchText);
$replace = array();
foreach ($searches as $i => $search){
preg_match_all('/'.$search.'/i',$fullText, $matches);
if ($matches){
$fullText = preg_replace('/'.$search.'/i', $matches[0][0].'<-', $fullText);
}
}
return $fullText;
}
Или, получив позицию строки и вставив '<-' в вычисленную позицию
function my_replace(string $fullText, string $searchText){
$searches = explode(' ',$searchText);
$replace = array();
foreach ($searches as $i => $search){
$position = strlen($search)+stripos($fullText, $search);
$fullText = substr_replace($fullText, '<- ', $position, 0);
}
return $fullText;
}
Надеюсь, что это поможет вам
В этом ответе слишком много нежелательного. Вызов preg_match_all() и preg_replace() на каждой итерации не требует дополнительных затрат, учитывая, что preg_match_all() вообще не нужен (см. Мой ответ). В объявлении $i нет необходимости, потому что он никогда не используется. Regex имеет группы захвата, поэтому вам не нужно использовать предварительно сгенерированные переменные в качестве параметра замены. Повторные вызовы preg_replace() тоже не нужны (опять же, см. Мой ответ). Ваша функция, отличная от регулярного выражения, завершается ошибкой при обнаружении несоответствующей строки поиска. 3v4l.org/TbOqp
Спасибо! Я выбрал @Rahul для простоты! Но я тоже очень ценю ваш код!