Обратные htmlentities/html_entity_decode
В основном я хочу повернуть строку следующим образом:
<code> <div> blabla </div> </code>
в это:
<code> <div> blabla </div> </code>
Как я могу это сделать?
Пример использования (bc некоторым людям было любопытно):
Страница, например , со списком разрешенных тегов и примеров HTML. Например, <code>
является допустимым тегом, и это будет образец:
<code><?php echo "Hello World!"; ?></code>
Мне нужна обратная функция, потому что есть много таких тегов с образцами, которые хранят их все в массиве, который я повторяю в одном цикле, вместо того, чтобы обрабатывать каждый отдельно...
Ответы
Ответ 1
Моя версия с использованием регулярных выражений:
$string = '<code> <div> blabla </div> </code>';
$new_string = preg_replace(
'/(.*?)(<.*?>|$)/se',
'html_entity_decode("$1").htmlentities("$2")',
$string
);
Он пытается сопоставить каждый тег и textnode, а затем применить htmlentities и html_entity_decode соответственно.
Ответ 2
Нет существующей функции, но посмотрите на это.
Пока я тестировал его только на вашем примере, но эта функция должна работать с all htmlentities
function html_entity_invert($string) {
$matches = $store = array();
preg_match_all('/(&(#?\w){2,6};)/', $string, $matches, PREG_SET_ORDER);
foreach ($matches as $i => $match) {
$key = '__STORED_ENTITY_' . $i . '__';
$store[$key] = html_entity_decode($match[0]);
$string = str_replace($match[0], $key, $string);
}
return str_replace(array_keys($store), $store, htmlentities($string));
}
Обновление:
-
Спасибо @Mike за то, что уделили время проверке моей функции другими строками. Я обновил свое регулярное выражение от /(\&(.+)\;)/
до /(\&([^\&\;]+)\;)/
, которое должно заботиться о проблеме, которую он поднял.
-
Я также добавил {2,6}
, чтобы ограничить длину каждого совпадения, чтобы уменьшить вероятность ложных срабатываний.
-
Изменено регулярное выражение от /(\&([^\&\;]+){2,6}\;)/
до /(&([^&;]+){2,6};)/
, чтобы удалить ненужное извлечение.
-
Whooa, brainwave! Изменено регулярное выражение от /(&([^&;]+){2,6};)/
до /(&(#?\w){2,6};)/
, чтобы еще больше уменьшить вероятность ложных срабатываний!
Ответ 3
Замена одного будет недостаточно для вас. Будь то регулярные выражения или простая замена строки, потому что, если вы замените знаки & lt > gt, тогда < и > или наоборот, вы получите одно кодирование/декодирование (все < lt и > gt или все знаки < и > ).
Итак, если вы хотите это сделать, вам придется разобрать один набор (я выбрал замену держателем места), замените его, а затем верните обратно и сделайте еще одну замену.
$str = "<code> <div> blabla </div> </code>";
$search = array("<",">",);
//place holder for < and >
$replace = array("[","]");
//first replace to sub out < and > for [ and ] respectively
$str = str_replace($search, $replace, $str);
//second replace to get rid of original < and >
$search = array("<",">");
$replace = array("<",">",);
$str = str_replace($search, $replace, $str);
//third replace to turn [ and ] into < and >
$search = array("[","]");
$replace = array("<",">");
$str = str_replace($search, $replace, $str);
echo $str;
Ответ 4
Я думаю, что у меня небольшое разрешение, почему бы не разбить html-теги на массив, а затем сравнить и изменить при необходимости?
function invertHTML($str) {
$res = array();
for ($i=0, $j=0; $i < strlen($str); $i++) {
if ($str{$i} == "<") {
if (isset($res[$j]) && strlen($res[$j]) > 0){
$j++;
$res[$j] = '';
} else {
$res[$j] = '';
}
$pos = strpos($str, ">", $i);
$res[$j] .= substr($str, $i, $pos - $i+1);
$i += ($pos - $i);
$j++;
$res[$j] = '';
continue;
}
$res[$j] .= $str{$i};
}
$newString = '';
foreach($res as $html){
$change = html_entity_decode($html);
if($change != $html){
$newString .= $change;
} else {
$newString .= htmlentities($html);
}
}
return $newString;
}
Изменено.... без ошибок.
Ответ 5
Итак, хотя другие люди здесь рекомендуют регулярные выражения, которые могут быть абсолютно правильным способом... Я хотел опубликовать это, поскольку этого достаточно для заданного вами вопроса.
Предполагая, что вы всегда используете код html'esque:
$str = '<code> <div> blabla </div> </code>';
xml_parse_into_struct(xml_parser_create(), $str, $nodes);
$xmlArr = array();
foreach($nodes as $node) {
echo htmlentities('<' . $node['tag'] . '>') . html_entity_decode($node['value']) . htmlentities('</' . $node['tag'] . '>');
}
Дает мне следующий результат:
<CODE> <div> blabla </div> </CODE>
Справедливо уверен, что это не будет способствовать возвращению назад. Как и другие опубликованные решения, в смысле:
$orig = '<code> <div> blabla </div> </code>';
$modified = '<CODE> <div> blabla </div> </CODE>';
$modifiedAgain = '<code> <div> blabla </div> </code>';
Ответ 6
Изменить: Похоже, я не полностью ответил на ваш вопрос. Нет встроенной функции PHP, чтобы делать то, что вы хотите, но вы можете найти и заменить регулярными выражениями или даже простыми выражениями: str_replace, preg_replace
Ответ 7
Я бы рекомендовал использовать регулярное выражение, например. preg_replace():