удалить тег сценария из содержимого HTML

Я использую HTML очиститель (http://htmlpurifier.org/)

Я просто хочу удалить теги <script> . Я не хочу удалять встроенное форматирование или любые другие вещи.

Как я могу это достичь?

Еще одна вещь: есть ли другой способ удалить теги скриптов из HTML

Поскольку этот вопрос помечен регулярным выражением, я собираюсь ответить с решением бедного человека в этой ситуации:

 $html = preg_replace('#<script(.*?)>(.*?)</script>#is', '', $html); 

Однако регулярные выражения не предназначены для синтаксического разбора HTML / XML, даже если вы пишете идеальное выражение, оно в конечном итоге сломается, это не стоит того, хотя в некоторых случаях полезно быстро исправить некоторую разметку и, как и при быстрых исправлениях, забыть о безопасности . Используйте регулярное выражение только по содержимому / разметке, которому вы доверяете.

Помните, что все, что пользовательские входы должны считаться небезопасными .

DOMDocument решением здесь будет использование DOMDocument который предназначен для этого. Вот фрагмент, который демонстрирует, насколько легко, чисто (по сравнению с регулярным выражением), (почти) надежным и (почти) безопасным, сделать то же самое:

 <?php $html = <<<HTML ... HTML; $dom = new DOMDocument(); $dom->loadHTML($html); $script = $dom->getElementsByTagName('script'); $remove = []; foreach($script as $item) { $remove[] = $item; } foreach ($remove as $item) { $item->parentNode->removeChild($item); } $html = $dom->saveHTML(); 

Я умышленно удалил HTML, потому что даже это может быть bork .

Используйте парсер PHP DOMDocument .

 $doc = new DOMDocument(); // load the HTML string we want to strip $doc->loadHTML($html); // get all the script tags $script_tags = $doc->getElementsByTagName('script'); $length = $script_tags->length; // for each tag, remove it from the DOM for ($i = 0; $i < $length; $i++) { $script_tags->item($i)->parentNode->removeChild($script_tags->item($i)); } // get the HTML string back $no_script_html_string = $doc->saveHTML(); 

Это помогло мне использовать следующий HTML-документ:

 <!doctype html> <html> <head> <meta charset="utf-8"> <title> hey </title> <script> alert("hello"); </script> </head> <body> hey </body> </html> 

Просто имейте в виду, что парсер DOMDocument требует PHP 5 или выше.

Я бы использовал BeautifulSoup, если он доступен. Делает это очень легко.

Не пытайтесь делать это с помощью регулярных выражений. Таким образом, безумие.

Я боролся с этим вопросом. Я обнаружил, что вам действительно нужна только одна функция. explode ('>', $ html); Единым общим знаменателем для любого тега является <и>. Затем после этого это обычно кавычки («). Вы можете легко извлечь информацию, как только найдете общий знаменатель. Это то, что я придумал:

 $html = file_get_contents('http://some_page.html'); $h = explode('>', $html); foreach($h as $k => $v){ $v = trim($v);//clean it up a bit if(preg_match('/^(<script[.*]*)/ius', $v)){//my regex here might be questionable $counter = $k;//match opening tag and start counter for backtrace }elseif(preg_match('/([.*]*<\/script$)/ius', $v)){//but it gets the job done $script_length = $k - $counter; $counter = 0; for($i = $script_length; $i >= 0; $i--){ $h[$k-$i] = '';//backtrace and clear everything in between } } } for($i = 0; $i <= count($h); $i++){ if($h[$i] != ''){ $ht[$i] = $h[$i];//clean out the blanks so when we implode it works right. } } $html = implode('>', $ht);//all scripts stripped. echo $html; 

Я вижу, что это действительно работает только для скриптовых тегов, потому что у вас никогда не будет вложенных тегов скрипта. Конечно, вы можете легко добавить еще один код, который выполняет ту же проверку и собирает вложенные теги.

Я называю это аккордеонным кодированием. лопаются (); взорваться (); это самые простые способы, чтобы ваша логика протекала, если у вас есть общий знаменатель.

Короче:

$html = preg_replace("/<script.*?\/script>/s", "", $html);

При выполнении регулярных выражений все может пойти не так, так что безопаснее делать вот так:

$html = preg_replace("/<script.*?\/script>/s", "", $html) ? : $html;

Так что, когда происходит «авария», мы получаем исходный $ html вместо пустой строки.

  • это слияние как ClandestineCoder & Binh WPO .

проблема с стрелками тега сценария заключается в том, что они могут иметь более одного варианта

ех. ( &lt; = &amp;lt; ) & ( &gt; = &amp;gt; &gt; = &amp;gt; ) &amp;gt;

поэтому вместо создания массива шаблонов, как вариант bazillion, imho лучшим решением будет

 return preg_replace('/script.*?\/script/ius', '', $text) ? preg_replace('/script.*?\/script/ius', '', $text) : $text; 

это удалит все, что похоже на script.../script независимо от кода / варианта стрелки, и вы можете проверить его здесь. https://regex101.com/r/lK6vS8/1

Пример модификации ответа ctf0. Это нужно сделать только для preg_replace один раз, а также проверить наличие ошибок и заблокировать код для косой черты.

 $str = '<script> var a - 1; <&#47;script>'; $pattern = '/(script.*?(?:\/|&#47;|&#x0002F;)script)/ius'; $replace = preg_replace($pattern, '', $str); return ($replace !== null)? $replace : $str; 

Если вы используете php 7, вы можете использовать оператор null coalesce, чтобы упростить его еще больше.

 $pattern = '/(script.*?(?:\/|&#47;|&#x0002F;)script)/ius'; return (preg_replace($pattern, '', $str) ?? $str);