基本上我想要像这样转换一个字符串:
<code> <div> blabla </div> </code>
进入这个:
<code> <div> blabla </div> </code>
我该怎么做?
用例(某些人很好奇):
像这样的页面 这个 包含允许的HTML标记和示例列表。例如, <code>
是一个允许的标签,这将是样本:
<code><?php echo "Hello World!"; ?></code>
我想要一个反向函数,因为有许多这样的标签带有样本,我将它们全部存储到一个数组中,我在一个循环中迭代,而不是单独处理每个...
我的版本使用正则表达式:
$string = '<code> <div> blabla </div> </code>';
$new_string = preg_replace(
'/(.*?)(<.*?>|$)/se',
'html_entity_decode("$1").htmlentities("$2")',
$string
);
它试图匹配每一个 标签 和 textnode 然后申请 ヶ辆 和 html_entity_decode 分别。
没有现有的功能,但看看这个。
到目前为止,我只在你的例子中测试了它,但是这个函数应该可以工作 所有 ヶ辆
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));
}
更新:
谢谢 @麦克风 花时间用其他字符串测试我的函数。我已经更新了我的正则表达式 /(\&(.+)\;)/
至 /(\&([^\&\;]+)\;)/
应该照顾他提出的问题。
我还补充道 {2,6}
限制每场比赛的长度,以减少误报的可能性。
改变了正则表达式 /(\&([^\&\;]+){2,6}\;)/
至 /(&([^&;]+){2,6};)/
删除不必要的兴奋。
哇,脑波!改变了正则表达式 /(&([^&;]+){2,6};)/
至 /(&(#?\w){2,6};)/
减少误报的可能性 更深入!
单独更换对你来说不够好。无论是正则表达式还是简单的字符串替换,因为如果您替换&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;
我想我有一个小的解决方案,为什么不将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;
}
修改....没有错误。
所以,虽然这里的其他人推荐了正则表达式,这可能是绝对正确的方式...我想发布这个,因为它足以满足你提出的问题。
假设你总是使用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>';
编辑:似乎我还没有完全回答你的问题。没有内置的PHP函数可以执行您想要的操作,但您可以使用正则表达式甚至简单表达式查找和替换: str_replace函数, 的preg_replace