求问有没有自动闭合 HTML 标签的轮子

2020-02-07 21:11:23 +08:00
 IDCFAN
用户在 textarea 里输入 HTML,可能存在输入不完整的情况,比如:

<a href=www>我很大

上面少了</a>,这样前台显示的时候会造成页面错乱。

求问有没有可以在入库的时候自动补上</a>的 PHP 函数。

帮忙的大佬先祝您佛光保佑,退散恶灵,全家安康。谢谢。
4763 次点击
所在节点    PHP
12 条回复
jugelizi
2020-02-07 21:18:11 +08:00
有个东西叫富文本编辑器 自定义配置
IDCFAN
2020-02-07 21:27:58 +08:00
@jugelizi 谢谢。但是我这情况是不超过 100 字符的一小段文本,富文本有点大材小用。
Sunyanzi
2020-02-07 22:03:17 +08:00
php 专门有个扩展做这个 ... php.net/tidy.repairstring 供参考 ...
imn1
2020-02-07 22:05:39 +08:00
这个比较难

例一
<a href=www>我很大
……
上面少了</a>

这几行算不算已经闭合?如果不计算最后一行,那么</a>加在省略号前还是后才算正确?

例二
<div>
<div></div>
<div></div>

那么</div>加在哪一行?
IDCFAN
2020-02-07 22:22:32 +08:00
@Sunyanzi 谢谢大佬。

@imn1 我找到了个轮子试了一下。第一种情况不处理,直接入库。第二种情况处理成下面这样。

<div>
<div></div>
<div></div></div>

感觉上还行。
greed1is9good
2020-02-07 22:31:26 +08:00
一般只能做总体的数量检验吧,像好多语言的括号一样数量不成对就报错,无法编译,其实少了“<>”这两个个符号的任一个也很麻烦。。。
no1xsyzy
2020-02-07 23:10:57 +08:00
一种是构造出树再重新组合,还有一种邪道是显示时每个丢进 iframe。
但还是不建议允许用户使用 html (就怕自己某天偷懒 /后续维护者不懂,导致用户输入不过滤直接插 <script> 进网页里形成 XSS ),BBcode 或者 Markdown 都是不错的选择。


另外,不成对的尖括号如何处理?
〔由上式可知,b<a 〕
内容根本不是标签如何处理?
〔看这个:<https://www.v2ex.com/t/642852>〕
关于其是否是标签具有歧义的如何处理?
〔<ruby>明日<rp>(</rp><rt>Tomorrow</rt><rp>)</rp></ruby>〕
〔参考这本书:<ruby on rails tutorial>〕
hundan
2020-02-08 01:40:30 +08:00
拜托你找到解决办法之后分享出来
loading
2020-02-08 09:37:57 +08:00
既然找到个轮子就应该贴出来,以后别人遇到和你一样问题的时候,可以帮到他。
不然以后就没人会回答你的问题了。

请参阅《提问的智慧》
mostkia
2020-02-08 10:20:04 +08:00
试试 Ace Editor 编辑器吧,这玩意儿可以方便的集成到自己的项目中,功能很强大,你拿它甚至能在 web 页面里写出 IDE 来。
7gugu
2020-02-08 10:52:22 +08:00
你写成树之后,匹配一下吧
IDCFAN
2020-02-08 11:52:02 +08:00
@hundan
@loading
其实我昨天就把这代码贴在回帖框里准备发一下,但是自己看不懂,只是自己感觉将就能用,也不知道这函数成熟不成熟,所以最终没发。既然大家说了,我就发一下,从 gayhub 扒下来的,大佬们顺便帮看看吧。其实感觉 3 楼 @Sunyanzi 用 PHP 扩展的方式更好,只是我比较菜,大概率不会弄。


function CloseTags($html)
{
$html = preg_replace('/<[^>]*$/', '', $html);
preg_match_all('#<([a-z1-6]+)(?: .*)?(?<![/|/ ])>#iU', $html, $result);
$opentags = $result[1];
preg_match_all('#</([a-z1-6]+)>#iU', $html, $result);
$closetags = $result[1];
$len_opened = count($opentags);
if (count($closetags) == $len_opened) {
return $html;
}
$opentags = array_reverse($opentags);
$sc = array('br', 'input', 'img', 'hr', 'meta', 'link');
for ($i = 0; $i < $len_opened; $i++) {
$ot = strtolower($opentags[$i]);
if (!in_array($opentags[$i], $closetags) && !in_array($ot, $sc)) {
$html .= '</' . $opentags[$i] . '>';
} else {
unset($closetags[array_search($opentags[$i], $closetags)]);
}
}
return $html;
}

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/642852

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX