JastaFly
@JastaFly

Странное поведение str_replace() при заменах в HTML?

Мне нужно заменить биты ссылки в HTML коде:
<p style="text-align: justify;">
	 Many some boring text without images <a href="https://www.some-site.com/some/site/section /" target="_blank">some link text</a> - still some boring text without images
</p>

В конце ссылки перед слешем стоит пробел что ломает её. Но суть не в этом, для решения задачи я написал регулярку, которую засунул в функцию preg_replace_callback():
$textWithoutSpaces = preg_replace_callback(
                '/(https:\/\/[\w_-]+(?:(?:\.[\w_-]+)+)[\w.,@?^=%&:\/~+#-]*[\w][ ]{1,}\/)/',
                'self::deleteSpaces',
                $text
            );

Для того чтобы изменить ссылки в HTML использовал следующую конструкцию:
private static function deleteSpaces($match) {
        return str_replace($match, str_replace(' ', '', $match), self::$currentText);
    }

Совпадения по регулярке в $match, отлично находятся, эта конструкция:
str_replace(' ', '', $match)
Отлично убирает из них пробелы, вся проблема в том что в итоговый HTML код попадает лишний кусок взявшийся хрен знает от куда, который дублирует часть текста:
<p style="text-align: justify;">
         Many some boring text without images <a href="<p style="text-align: justify;">
	 Many some boring text without images <a href="https://www.some-site.com/some/site/section /" target="_blank">some link text</a> - still some boring text without images
</p>

Пробовал переписать на:
private static function deleteSpaces($match) {
        $positionToText = strpos(self::$currentEnDetailNewsText, $match);
        return substr_replace(self::$currentEnDetailNewsText, str_replace(' ', '', $match), $positionToText, strlen($match));
    }

Результат идентичен. Подскажите что не так? Или может быть какой-то альтернативный способ?
  • Вопрос задан
  • 203 просмотра
Решения вопроса 1
IvanU7n
@IvanU7n
nothing interesting here
Подскажите что не так?

в нежелании читать документацию

в колбэк $match приходит в виде массива, с используемой регуляркой нужно использовать либо $match[0], либо $match[1]

далее, из колбэка нужно возвращать исправленную ссылку, а не (судя по коду) целиком фрагмент с исправленной ссылкой
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
ThunderCat
@ThunderCat Куратор тега PHP
{PHP, MySql, HTML, JS, CSS} developer
$html = str_replace(' /" ', '/" ' ,$html);Есть ненулевая вероятность попасть в какой-то текст, но в целом ей можно пренебречь.
Ответ написан
Комментировать
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Работать регулярками с HTML можно, но сложно.
Проще использовать библиотеку, предназначенную для этого, например Simple HTML DOM Parser.
Ответ написан
Ваш ответ на вопрос

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

Похожие вопросы