找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 1528|回复: 0
打印 上一主题 下一主题

PHP 修复未正常关闭的HTML标签实现代码(支持嵌套和就近闭合)

[复制链接]

2647

主题

2647

帖子

7881

积分

论坛元老

Rank: 8Rank: 8

积分
7881
跳转到指定楼层
楼主
发表于 2018-2-14 08:28:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

            fixHtmlTag
version 0.2
这个版本解决了上次遗留的问题,即就近闭合和嵌套闭合问题。具体可以看代码的注释。
[U]复制代码[/U] 代码如下:
你好"
* 这样的 html 代码会被修改为 "你好"
* 2,就近闭合模式,CLOSE,这种模式会将形如 "你好为什么没有
* 闭合呢" 的代码修改为 "你好
为什么没有闭合呢
"
*
* 在嵌套闭合模式(默认,无需特殊传参)下,可以传入需要就近闭合的
* 标签名,通过这种方式将类似 "你好
我也好" 转换为
* "你好
我也好
"的形式。
* 传参时索引需要按照如下方式写,不需要修改的设置可以省略
*
* $param = array(
* 'html' => '', //必填
* 'options' => array(
* 'tagArray' => array();
* 'type' => 'NEST',
* 'length' => null,
* 'lowerTag' => TRUE,
* 'XHtmlFix' => TRUE,
* )
* );
* fixHtmlTag($param);
*
* 上面索引对应的值含义如下
* string $html 需要修改的 html 代码
* array $tagArray 当为嵌套模式时,需要就近闭合的标签数组
* string $type 模式名,目前支持 NEST 和 CLOSE 两种模式,如果设置为 CLOSE,将会忽略参数 $tagArray 的设置,而全部就近闭合所有标签
* ini $length 如果希望截断一定长度,可以在此赋值,此长度指的是字符串长度
* bool $lowerTag 是否将代码中的标签全部转换为小写,默认为 TRUE
* bool $XHtmlFix 是否处理不符合 XHTML 规范的标签,即将
转换为

*
* @author IT不倒翁
* @version 0.2
* @link http://yungbo.com IT不倒翁
* @link http://enenba.com/?post=19 某某
* @param array $param 数组参数,需要赋予特定的索引
* @return string $result 经过处理后的 html 代码
* @since 2012-04-14
*/
function fixHtmlTag($param = array()) {
//参数的默认值
$html = '';
$tagArray = array();
$type = 'NEST';
$length = null;
$lowerTag = TRUE;
$XHtmlFix = TRUE;
//首先获取一维数组,即 $html 和 $options (如果提供了参数)
extract($param);
//如果存在 options,提取相关变量
if (isset($options)) {
extract($options);
}
$result = ''; //最终要返回的 html 代码
$tagStack = array(); //标签栈,用 array_push() 和 array_pop() 模拟实现
$contents = array(); //用来存放 html 标签
$len = 0; //字符串的初始长度
//设置闭合标记 $isClosed,默认为 TRUE, 如果需要就近闭合,成功匹配开始标签后其值为 false,成功闭合后为 true
$isClosed = true;
//将要处理的标签全部转为小写
$tagArray = array_map('strtolower', $tagArray);
//“合法”的单闭合标签
$singleTagArray = array(
']+?>)/si", $html, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
foreach ($contents as $tag) {
if ('' == trim($tag)) {
$result .= $tag;
continue;
}
//匹配标准的单闭合标签,如

if (preg_match("/]*?\/>/si", $tag)) {
$result .= $tag;
continue;
}
//匹配开始标签,如果是单标签则出栈
else if (preg_match("/]*?>/si", $tag, $match)) {
//如果上一个标签没有闭合,并且上一个标签属于就近闭合类型
//则闭合之,上一个标签出栈
//如果标签未闭合
if (false === $isClosed) {
//就近闭合模式,直接就近闭合所有的标签
if ('CLOSE' == $type) {
$result .= '';
array_pop($tagStack);
}
//默认的嵌套模式,就近闭合参数提供的标签
else {
if (in_array(end($tagStack), $tagArray)) {
$result .= '';
array_pop($tagStack);
}
}
}
//如果参数 $lowerTag 为 TRUE 则将标签名转为小写
$matchLower = $lowerTag == TRUE ? strtolower($match[1]) : $match[1];
$tag = str_replace('', ' />', $tag);
}
array_pop($tagStack);
}
}
//就近闭合模式,状态变为未闭合
if ('CLOSE' == $type) {
$isClosed = false;
}
//默认的嵌套模式,如果标签位于提供的 $tagArray 里,状态改为未闭合
else {
if (in_array($matchLower, $tagArray)) {
$isClosed = false;
}
}
unset($matchLower);
}
//匹配闭合标签,如果合适则出栈
else if (preg_match("/]*?>/si", $tag, $match)) {
//如果参数 $lowerTag 为 TRUE 则将标签名转为小写
$matchLower = $lowerTag == TRUE ? strtolower($match[1]) : $match[1];
if (end($tagStack) == $matchLower) {
$isClosed = true; //匹配完成,标签闭合
$tag = str_replace('/si", $tag)) {
$result .= $tag;
}
//将字符串放入 $result ,顺便做下截断操作
else {
if (is_null($length) || $len + mb_strlen($tag) ';
}
return $result;
}
            
            
您可能感兴趣的文章:
  • PHP html标签正则替换并可自定义正则规则
  • PHP实现HTML标签自动补全代码
  • php使HTML标签自动补全闭合函数代码
  • php中将html中的br换行符转换为文本输入中的换行符
  • PHP删除HTMl标签的三种解决方法
  • php去除HTML标签实例
  • php 批量替换html标签的实例代码
  • PHP中HTML标签过滤技巧
  • php获取网页标题和内容函数(不包含html标签)
  • php过滤HTML标签、属性等正则表达式汇总
  • php实现过滤表单提交中html标签的方法
  • PHP将HTML转换成文本的实现代码
  • PHP转换文本框内容为HTML格式的方法
  • php自定义函数转换html标签示例
            
  • 分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    用户反馈
    客户端