Как лучше организовать замену текста в строке?

Есть строка вида
$myString='Текст, ещё текст ABCDEF ещё текст текст GHJKL -- много текста MNOP и напоследок снова ABCDEF конец';

То есть обычная строка, в которой есть текст, который надо заменить на другой.
(для простоты я написал текст для замены заглавными английскими, для примера)

Например, необходимо заменить текст ABCDEF на AAA
текст GHJKL на BBB
текст ABCDEF (тот что в конце) на CCC
То есть, текст в строке может совпадать с предыдущим (регулярки не подойдут), важна позиция текста.

На текущий момент я знаю (написал код который находит): начало текста, длину текста, окончание текста, сам текст.
То есть текст ABCDEF начинается с 18 символа и заканчивается 24 символом, длина 6. И так для каждого текста.

Как теперь сделать замену?

PS
Пока на ум приходит только вариант - разрезать и соединять строки.
Например при ABCDEF
отрезаем из исходной строки строку с 0 до 18 символа
вставляем AAA
отрезаем из исходной строки строку с 24 символа (до следующего начала замены)
отрезали до, вставили замену, доклеили после....
  • Вопрос задан
  • 137 просмотров
Пригласить эксперта
Ответы на вопрос 5
AgentSmith
@AgentSmith
Это мой правильный ответ на твой вопрос
регулярки не подойдут

Почему это не подойдут?
Можно и регулярками заменять только первое совпадение:
^(.*?)\bABCDEF\b
replace: "\1AAA"

https://regex101.com/r/9ud84G/1
Ответ написан
@entermix
$str = 'Текст, ещё текст ABCDEF ещё текст текст GHJKL -- много текста MNOP и напоследок снова ABCDEF конец';

$replaces = [['text' => 'ABCDEF', 'replace' => 'AAA', 'limit' => 1], ['text' => 'GHJKL', 'replace' => 'BBB'], ['text' => 'ABCDEF', 'replace' => 'CCC']];

foreach ($replaces as $replace){
	$str = preg_replace('#' . $replace['text'] . '#', $replace['replace'], $str, ($replace['limit'] ?? -1));
}

echo $str;


https://onlinephp.io/c/a12a0
Ответ написан
ThunderCat
@ThunderCat Куратор тега PHP
{PHP, MySql, HTML, JS, CSS} developer
Решение "в лоб":
1) В соответствующие позиции перед и после нужного слова добавляем символы, например |
2) Делаем так со всеми словами, естественно вставки производим с конца текста к началу, дабы не сбить позиции.
3) Заменяем все простым реплэйсом, добавляя в паттерны замены нужные символы.

Как я и писал в комментариях, 90% что вы решаете стандартно банальную задачу через пятую точку, и есть способ проще и эффективнее.
Ответ написан
gzhegow
@gzhegow
aka "ОбнимиБизнесмена"
<?php

$words = [
  [ 'ABCDEF', 'textA' ], // 1
  [ 'GHJKL', 'textB' ], // 2
  [ 'MNOP', 'textC' ], // 3
  [ 'ABCDEF', 'textD' ], // 4
];

$result = $str = 'Текст, ещё текст ABCDEF ещё текст текст GHJKL -- много текста MNOP и напоследок снова ABCDEF конец';

// 4 -> 3 -> 2 -> 1 (array_pop)
while ([ $word, $replacement ] = array_pop($words)) {
  // @gzhegow > do you need 'mb_' ? is it UTF-8 text?
  if (false !== ($pos = mb_strrpos($result, $word))) { // ищем номер первой буквы совпадения с конца строки в начало
    $result = ''
      . mb_substr($result, 0, $pos) // до первой буквы
      . $replacement // замена
      . mb_substr($result, $pos + mb_strlen($word)) // после последней буквы
    ;
  }
}

var_dump($result);

// string(155) "Текст, ещё текст textA ещё текст текст textB -- много текста textC и напоследок снова textD конец"
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы