htmlentities в PHP но сохранение html тегов
Я хочу конвертировать все тексты в строку в HTML-сущности, но сохраняя HTML-теги, например:
<p><font style="color:#FF0000">Camión español</font></p>
должно быть переведено на это:
<p><font style="color:#FF0000">Camión español</font></p>
какие идеи?
7 ответов:
вы можете получить список символов соответствий = > сущность, используемая
htmlentities
С функциейget_html_translation_table
; рассмотрим этот код :$list = get_html_translation_table(HTML_ENTITIES); var_dump($list);
(вы можете проверить второй параметр этой функции в руководстве - возможно, вам нужно будет установить его значение, отличное от значения по умолчанию)
он будет Вам что-то вроде этого :
array ' ' => string ' ' (length=6) '¡' => string '¡' (length=7) '¢' => string '¢' (length=6) '£' => string '£' (length=7) '¤' => string '¤' (length=8) .... .... .... 'ÿ' => string 'ÿ' (length=6) '"' => string '"' (length=6) '<' => string '<' (length=4) '>' => string '>' (length=4) '&' => string '&' (length=5)
теперь удалите корреспонденции вы не хочу :
unset($list['"']); unset($list['<']); unset($list['>']); unset($list['&']);
теперь в вашем списке есть все символы соответствия = > сущности, используемые htmlentites, за исключением нескольких символов, которые вы не хотите кодировать.
и теперь, вы просто должны извлечь список ключей и значений :
$search = array_keys($list); $values = array_values($list);
и, наконец, вы можете использовать str_replace для замены:
$str_in = '<p><font style="color:#FF0000">Camión español</font></p>'; $str_out = str_replace($search, $values, $str_in); var_dump($str_out);
а также вы получаете :
string '<p><font style="color:#FF0000">Camión español</font></p>' (length=84)
который выглядит так, как вы хотели ; -)
Edit: ну, за исключением проблемы кодирования (проклятый UTF-8, я полагаю - я пытаюсь найти решение для этого и снова отредактирую)второе редактирование через пару минут после : похоже, вам придется использовать
utf8_encode
на$search
список, прежде чем называтьstr_replace
: - (что означает использование чего-то вроде этого :
$search = array_map('utf8_encode', $search);
между вызовом
array_keys
, а вызовstr_replace
.и, на этот раз, вы действительно должны получить то, что вы хотели :
string '<p><font style="color:#FF0000">Camión español</font></p>' (length=70)
И вот полная часть кода:$list = get_html_translation_table(HTML_ENTITIES); unset($list['"']); unset($list['<']); unset($list['>']); unset($list['&']); $search = array_keys($list); $values = array_values($list); $search = array_map('utf8_encode', $search); $str_in = '<p><font style="color:#FF0000">Camión español</font></p>'; $str_out = str_replace($search, $values, $str_in); var_dump($str_in, $str_out);
и полной мощности :
string '<p><font style="color:#FF0000">Camión español</font></p>' (length=58) string '<p><font style="color:#FF0000">Camión español</font></p>' (length=70)
на этот раз, это должно быть ОК ^^
Он действительно не вписывается в одну строку, это может быть не самое оптимизированное решение ; но он должен работать нормально и имеет то преимущество, что позволяет добавлять/удалять любой символ соответствия => сущность, которая вам нужна или нет.удачи !
может быть не очень эффективно, но это работает
$sample = '<p><font style="color:#FF0000">Camión español</font></p>'; echo htmlspecialchars_decode( htmlentities($sample, ENT_NOQUOTES, 'UTF-8', false) , ENT_NOQUOTES );
это оптимизированная версия принятого ответа.
$list = get_html_translation_table(HTML_ENTITIES); unset($list['"']); unset($list['<']); unset($list['>']); unset($list['&']); $string = strtr($string, $list);
решения парсер будет правильным для всех случаев. Ваш хороший случай:
<p><font style="color:#FF0000">Camión español</font></p>
но вы также хотите поддержать:
<p><font>true if 5 < a && name == "joe"</font></p>
где вы хотите, чтобы вышло так:
<p><font>true if 5 < a && name == "joe"</font></p>
вопрос: Можете ли вы сделать кодировку, прежде чем строить HTML. Другими словами можно сделать что-то вроде:
"<p><font>" + htmlentities(inner) + "</font></p>"
вы сэкономите много горя, если вы можете сделать это. Если вы не можете, вам понадобится какой-то способ пропустить кодировку и " (как описано выше), или просто закодировать все это, а затем отменить его (например.
replace('<', '<')
)
это функция, которую я только что написал, которая решает эту проблему очень элегантно:
прежде всего, HTML-теги будут извлечены из строки, затем htmlentities() выполняется на каждой оставшейся подстроке, и после этого исходные HTML-теги будут вставлены в их старую позицию, что приведет к отсутствию изменения HTML-тегов. : -)
весело:
function htmlentitiesOutsideHTMLTags ($htmlText) { $matches = Array(); $sep = '###HTMLTAG###'; preg_match_all("@<[^>]*>@", $htmlText, $matches); $tmp = preg_replace("@(<[^>]*>)@", $sep, $htmlText); $tmp = explode($sep, $tmp); for ($i=0; $i<count($tmp); $i++) $tmp[$i] = htmlentities($tmp[$i]); $tmp = join($sep, $tmp); for ($i=0; $i<count($matches[0]); $i++) $tmp = preg_replace("@$sep@", $matches[0][$i], $tmp, 1); return $tmp; }
на основе ответа bflesch, я сделал некоторые изменения, чтобы управлять строку, содержащую
less than sign
,greater than sign
иsingle quote
илиdouble quotes
.function htmlentitiesOutsideHTMLTags ($htmlText, $ent) { $matches = Array(); $sep = '###HTMLTAG###'; preg_match_all(":</{0,1}[a-z]+[^>]*>:i", $htmlText, $matches); $tmp = preg_replace(":</{0,1}[a-z]+[^>]*>:i", $sep, $htmlText); $tmp = explode($sep, $tmp); for ($i=0; $i<count($tmp); $i++) $tmp[$i] = htmlentities($tmp[$i], $ent, 'UTF-8', false); $tmp = join($sep, $tmp); for ($i=0; $i<count($matches[0]); $i++) $tmp = preg_replace(":$sep:", $matches[0][$i], $tmp, 1); return $tmp; }
Пример использования:$string = '<b>Is 1 < 4?</b>è<br><i>"then"</i> <div style="some:style;"><p>gain some <strong>€</strong><img src="/some/path" /></p></div>'; $string_entities = htmlentitiesOutsideHTMLTags($string, ENT_QUOTES | ENT_HTML401); var_dump( $string_entities );
вывод:
string '<b>Is 1 < 4?</b>è<br><i>"then"</i> <div style="some:style;"><p>gain some <strong>€</strong><img src="/some/path" /></p></div>' (length=150)
Вы можете пройти любойent flag
по словам руководство по htmlentities
однострочное решение без таблицы перевода или пользовательской функции требуется:
Я знаю, что это старый вопрос, но недавно мне пришлось импортировать статический сайт на сайт wordpress и пришлось преодолеть эту проблему:
вот мое решение, которое не требует манипуляций с таблицами перевода :
htmlspecialchars_decode( htmlentities( html_entity_decode( $string ) ) );
при применении к строке OP:
<p><font style="color:#FF0000">Camión español</font></p>
выход:
<p><font style="color:#FF0000">Camión español</font></p>
при нанесении лука строка:
<b>Is 1 < 4?</b>è<br><i>"then"</i> <div style="some:style;"><p>gain some <strong>€</strong><img src="/some/path" /></p></div>
выход:
<b>Is 1 < 4?</b>è<br><i>"then"</i> <div style="some:style;"><p>gain some <strong>€</strong><img src="/some/path" /></p></div>
EDIT: это работает особенно хорошо, "отбеливая" входную строку сначала:
$string = preg_replace( '/[^\x00-\x7F]/', null, $string ); htmlspecialchars_decode( htmlentities( html_entity_decode( $string ) ) );
теперь $ string ооочень красиво!!