Подтвердить что ты не робот

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

У меня есть этот html-код:

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

но он должен стать (для всех возможных html-тегов):

<p>
<strong>hello</strong>
</p>
4b9b3361

Ответ 1

Адаптирован из моего ответа по аналогичному вопросу

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

echo preg_replace("/<([a-z][a-z0-9]*)[^>]*?(\/?)>/i",'<$1$2>', $text);

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

Разделение RegExp:

/              # Start Pattern
 <             # Match '<' at beginning of tags
 (             # Start Capture Group $1 - Tag Name
  [a-z]         # Match 'a' through 'z'
  [a-z0-9]*     # Match 'a' through 'z' or '0' through '9' zero or more times
 )             # End Capture Group
 [^>]*?        # Match anything other than '>', Zero or More times, not-greedy (wont eat the /)
 (\/?)         # Capture Group $2 - '/' if it is there
 >             # Match '>'
/i            # End Pattern - Case Insensitive

Добавьте некоторые цитаты и используйте заменяющий текст <$1$2>, он должен лишить текст после тэга до конца тега /> или просто >.

Обратите внимание. Это не обязательно будет работать во всех входах, как сообщит вам Anti-HTML + RegExp. Есть несколько резервных копий, наиболее заметно <p style=">"> закончится <p>"> и несколькими другими проблемными проблемами... Я бы рекомендовал посмотреть Zend_Filter_StripTags как фильтр полных доказательств/атрибутов в PHP

Ответ 2

Вот как это сделать с помощью собственного DOM:

$dom = new DOMDocument;                 // init new DOMDocument
$dom->loadHTML($html);                  // load HTML into it
$xpath = new DOMXPath($dom);            // create a new XPath
$nodes = $xpath->query('//*[@style]');  // Find elements with a style attribute
foreach ($nodes as $node) {              // Iterate over found elements
    $node->removeAttribute('style');    // Remove style attribute
}
echo $dom->saveHTML();                  // output cleaned 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();

Ответ 3

Я бы не использовал регулярное выражение, поскольку HTML не является обычным языком и вместо этого использует синтаксический анализатор html, например Простой HTML DOM

Вы можете получить список атрибутов, которыми обладает объект, используя attr. Например:

$html = str_get_html('<div id="hello">World</div>');
var_dump($html->find("div", 0)->attr); /
/*
array(1) {
  ["id"]=>
  string(5) "hello"
}
*/

foreach ( $html->find("div", 0)->attr as &$value ){
    $value = null;
}

print $html
//<div>World</div>

Ответ 4

$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>');
$result = preg_replace('/<(\w+)[^>]*>/', '<$1>', $strip_text);
echo $result;

// Result
string 'Hello <b>world</b>. Its beautiful day.'

Ответ 5

Regex слишком хрупки для разбора HTML. В вашем примере следующие атрибуты будут отключены:

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

Обновление

Сделайте второй захват необязательным и не удаляйте '/' из закрывающих тегов:

|<(\w+)([^>]+)| до |<(\w+)([^>/]+)?|

Продемонстрируйте это регулярное выражение:

$ phpsh
Starting php
type 'h' or 'help' to see instructions & features
php> $html = '<p style="padding:0px;"><strong style="padding:0;margin:0;">hello<br/></strong></p>';
php> echo preg_replace("|<(\w+)([^>/]+)?|", "<$1", $html);
<p><strong>hello</strong><br/></p>
php> $html = '<strong>hello</strong>';
php> echo preg_replace("|<(\w+)([^>/]+)?|", "<$1", $html);
<strong>hello</strong>

Ответ 6

Надеюсь, это поможет. Возможно, это не самый быстрый способ сделать это, особенно для больших блоков 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);

Ответ 7

Чтобы сделать СПЕЦИАЛЬНО, чего хочет andufo, просто:

$html = preg_replace( "#(<[a-zA-Z0-9]+)[^\>]+>#", "\\1>", $html );

То есть, он хочет удалить что-либо, кроме имени тега, из открытого тега. Конечно, он не будет работать для самозакрывающихся тегов.

Ответ 8

<?php
$text = '<p>Test paragraph.</p><!-- Comment --> <a href="#fragment">Other text</a>';
echo strip_tags($text);
echo "\n";

// Allow <p> and <a>
echo strip_tags($text, '<p><a>');
?>