0

Удалить все атрибуты из HTML-тегов

45

У меня есть следующий HTML-код:

<p style="padding:0px;">
  <strong style="padding:0;margin:0;">hello</strong>
</p>

Как я могу удалить атрибуты из всех тегов? Я хотел бы, чтобы результат выглядел так:

<p>
  <strong>hello</strong>
</p>

Как правильно это сделать?

4 ответ(ов)

0

Вот как это можно сделать с использованием нативного DOM в PHP:

$dom = new DOMDocument;                 // Инициализируем новый DOMDocument
$dom->loadHTML($html);                  // Загружаем HTML
$xpath = new DOMXPath($dom);            // Создаем новый XPath
$nodes = $xpath->query('//*[@style]');  // Ищем элементы с атрибутом style
foreach ($nodes as $node) {              // Итерируемся по найденным элементам
    $node->removeAttribute('style');    // Удаляем атрибут style
}
echo $dom->saveHTML();                  // Выводим очищенный HTML

Если вам нужно удалить все возможные атрибуты со всех возможных тегов, сделайте следующее:

$dom = new DOMDocument;
$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
$nodes = $xpath->query('//@*');        // Ищем все атрибуты
foreach ($nodes as $node) {
    $node->parentNode->removeAttribute($node->nodeName); // Удаляем атрибут у родительского узла
}
echo $dom->saveHTML();                  // Выводим HTML без атрибутов

Таким образом, вы можете легко удалять как определенные атрибуты, так и все атрибуты из HTML-документа.

0

Для удаления всех HTML-тегов из строки, кроме определённых, можно использовать функцию strip_tags(). В вашем случае вы хотите сохранить теги <b>, но удалить остальные. Это можно сделать следующим образом:

$html_text = '<p>Hello <b onclick="alert(123)" style="color: red">world</b>. <i>Its beautiful day.</i></p>';
$strip_text = strip_tags($html_text, '<b>'); // Удаляем все теги, кроме <b>
$result = preg_replace('/<(\w+)[^>]*>/', '<$1>', $strip_text); // Убираем атрибуты у <b>
echo $result;

// Результат
// строка 'Hello <b>world</b>. Its beautiful day.'

В данном коде strip_tags() удаляет все HTML-теги, кроме <b>. Затем мы используем preg_replace(), чтобы убрать атрибуты из тега <b> (в данном случае onclick и style). В итоге мы получаем желаемую строку без атрибутов, но с сохранением нужного тега.

0

HTML-парсинг с помощью регулярных выражений очень хрупок. В вашем примере следующий код может удалить атрибуты:

echo preg_replace(
    "|<(\w+)([^>/]+)?|",
    "<$1",
    "<p style=\"padding:0px;\">\n<strong style=\"padding:0;margin:0;\">hello</strong>\n</p>\n"
);

Обновление

Чтобы второй захват был необязательным и не удалять '/' из закрывающих тегов, стоит изменить регулярное выражение с |<(\w+)([^>]+)| на |<(\w+)([^>/]+)?|.

Давайте продемонстрируем, что это регулярное выражение работает:

$html = '<p style="padding:0px;"><strong style="padding:0;margin:0;">hello<br/></strong></p>';
echo preg_replace("|<(\w+)([^>/]+)?|", "<$1", $html);

В результате мы получим:

<p><strong>hello</strong><br/></p>

Если использовать его на следующем фрагменте:

$html = '<strong>hello</strong>';
echo preg_replace("|<(\w+)([^>/]+)?|", "<$1", $html);

Результат будет:

<strong>hello</strong>

Имейте в виду, что использование регулярных выражений для HTML может привести к непредсказуемым результатам. Лучшим решением будет использование HTML-парсера, например, DOMDocument, который более надежен в обработке HTML.

0

Надеюсь, это поможет. Это может быть не самый быстрый способ сделать то, что нужно, особенно для больших блоков HTML. Если у кого-то есть предложения по улучшению производительности, дайте знать!

function StringEx($str, $start, $end)
{ 
    $str_low = strtolower($str);
    $pos_start = strpos($str_low, $start);
    $pos_end = strpos($str_low, $end, ($pos_start + strlen($start)));
    if($pos_end == 0) return false;
    if (($pos_start !== false) && ($pos_end !== false))
    {  
        $pos1 = $pos_start + strlen($start);
        $pos2 = $pos_end - $pos1;
        $RData = substr($str, $pos1, $pos2);
        if($RData == '') { return true; }
        return $RData;
    } 
    return false;
}

$S = '<'; $E = '>'; 
while($RData = StringEx($DATA, $S, $E)) { 
    if($RData == true) {$RData = '';} 
    $DATA = str_ireplace($S . $RData . $E, '||||||', $DATA); 
} 
$DATA = str_ireplace('||||||', $S . $E, $DATA);

В этом коде функция StringEx ищет подстроки между указанными символами начала и конца, возвращая их содержимое. В основном цикле мы заменяем найденные подстроки на фиктивное значение, чтобы избежать повторных замен. Это основной принцип работы кода, но еще раз отметим, что для больших объемов HTML может потребоваться оптимизация.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь