造轮子-html标签清理

这个是我去年处理RSS订阅源时写的小玩意,基于jsoup、正则完成的,有两种实现,看你想用哪一种,如果觉得对你有帮助,请点个赞吧。

HtmlTagClearUpTool.java

package org.wuancake.common.util;

/**
 * 过滤html字符串的标签
 *
 * @author 黑白大彩电
 * @Date 2018/5/21 12:06
 */
public class HtmlTagClearUpTool {

    /**
     * 白名单正则(过滤规则1、过滤规则2,都是白名单正则,保留指定标签,未被指定的会被剔除)
     * {
     * 标签中的文本会被保留,比如 : <p>案例</p> =》 案例
     * }
     * {
     * 白名单标签也会被保留
     * 比如白名单为<img>
     * <p>案例</p><img alt="图片" src="http://www.gamelook.com.cn/dh1.jpg"/> =》 案例<img alt="图片" src="http://www.gamelook.com.cn/dh1.jpg"/>
     * }
     */

    /**
     * 过滤规则1
     * 保留如下标签{
     * <a>链接标签</a>
     * <img alt="图片标签">
     * <iframe>引入外部页面标签</iframe>
     * <strong> 较粗标签</strong>
     * }
     */
    private static final String RULE_ONE = "(?!<(img|a|/a|iframe|/iframe|strong|/strong).*?>)<.*?>";

    /**
     * 过滤规则2,啥标签都不保留
     */
    private static final String RULE_TWO = "<.*?>";


    /**
     * 黑名单正则(过滤规则3、过滤规则4,都是黑名单正则,剔除指定标签,未被指定的会被保留)
     * {
     *      标签中的文本会被保留,比如 : <p>案例</p> =》 案例
     * }
     * {
     * 黑名单之外的标签会被保留
     * 比如名单为<a>
     * <p>案例<a  src="http://www.gamelook.com.cn/dh1.jpg">点击链接</a></p> =》 <p>案例点击链接</p>
     * }
     */

    /**
     * 过滤规则3
     * 剔除A标签、span标签
     */
    private static final String RULE_THREE = "(<\\/?a.*?>)|(<\\/?span.*?>)";

    /**
     * 过滤规则4
     * 剔除strong, a, font, span ,b, label, em, small,abbr, del 标签
     */
    private static final String r = "(<\\/?a.*?>)|(<\\/?span.*?>)|(<\\/?strong.*?>)|(<\\/?font.*?>)|(<\\/?b.*?>)|(<\\/?label.*?>)|(<\\/?em.*?>)|(<\\/?small.*?>)|(<\\/?abbr.*?>)|(<\\/?del.*?>)";

    //如果不满足你的需求,你可以参考这四个过滤规则,来自定义你的规则

    /**
     * 过滤html
     *
     * @param html
     * @param rule
     * @return
     */
    public static String clearUp(String html, String rule) {
        if (html == null || html.trim().length() < 1) {
            return html;
        }
        html = html.replaceAll(rule, "");
        return html;
    }

    public static void main(String[] args) {
        String html = "<p>文字文字<strong>加粗文字</strong>文字文字<img alt=\"图片\" src=\"http://www.gamelook.com.cn/dh1.jpg\"\"/>文字文字<a href=\"https://github.com/\">外部链接</a>文字文字</p>";
        System.out.println("原版html:" + html);
        System.out.println("使用过滤规则1:" + HtmlTagClearUpTool.clearUp(html, HtmlTagClearUpTool.RULE_ONE));
        System.out.println("使用过滤规则2:" + HtmlTagClearUpTool.clearUp(html, HtmlTagClearUpTool.RULE_TWO));

        html = "<p style=\"margin-left:0px;\">&gt; 实用、好用的&nbsp;<a href=\"https://sspai.com/mall\" target=\"_blank\">正版软件</a>,少数派为你呈现&nbsp;</p>\n";
        System.out.println("使用过滤规则3:\n" + html + "\n" + HtmlTagClearUpTool.clearUp(html, HtmlTagClearUpTool.RULE_THREE));

        /**
         * 输出结果:
         * 原版html:<p>文字文字<strong>加粗文字</strong>文字文字<img alt="图片" src="http://www.gamelook.com.cn/dh1.jpg""/>文字文字<a href="https://github.com/">外部链接</a>文字文字</p>
         * 使用过滤规则1:文字文字<strong>加粗文字</strong>文字文字<img alt="图片" src="http://www.gamelook.com.cn/dh1.jpg""/>文字文字<a href="https://github.com/">外部链接</a>文字文字
         * 使用过滤规则2:文字文字加粗文字文字文字文字文字外部链接文字文字
         */
    }
}

HtmlTagClearUpTool2.java

package org.wuancake.api;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Node;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * HTML过滤并格式化
 *
 * @author 黑白大彩电
 * @since 2020-04-22
 */

public class HtmlTagClearUpTool2 {
    public static void main(String[] args) throws IOException {
        String html = "<p>文字文字<strong>加粗文字</strong>文字文字</p>\n" +
                "\n" +
                "<p><img src=\"http://www.gamelook.com.cn/wp-content/uploads/2020/11/dh1.jpg\"/></p>\n" +
                "\n" +
                "<p>文字文字文字文字文字文字</p>\n" +
                "\n" +
                "<p>文字文字<a href=\"https://github.com/\">外部链接</a>文字文字</p>";

        html = "<html>\n" +
                " <head></head>\n" +
                " <body>\n" +
                "  <h2>OPPO 发布智能电视 S1/R1,无线耳机 Enco X</h2>\n" +
                "  <p>10 月 19 日,OPPO 举行「智美生活」发布会并推出智能电视 S1/R1、无线耳机 Enco X 等多款新品。</p>\n" +
                "  <p>OPPO TV S1 搭载联发科 MT9950 芯片,支持 Wi-Fi 6,提供 8.5GB + 128GB 版本;屏幕采用 65 英寸 QLED 量子点屏幕,分辨率可达 4K(3840×2160),支持 VRR 48Hz-120Hz 可变刷新率,拥有 NTSC 120% 超色域,直下式背光,210 分区控光和动态分区调光技术,峰值亮度 1500nits,游戏延迟低至 20ms;OPPO TV R1 则搭载 4K 分辨率悬浮全面屏,支持 93% P3 广色域;搭载了联发科四核 MT9652 芯片,支持 Wi-Fi 6,提供 HDMI 2.1 接口。</p>\n" +
                "  <figure class=\"image ss-img-wrapper\">\n" +
                "   <img src=\"http://dev-img.wuanlife.com/768208212183879680.png\">\n" +
                "   <figcaption>\n" +
                "    OPPO 智能电视 S1\n" +
                "   </figcaption>\n" +
                "  </figure>\n" +
                "  <p>售价方面,OPPO TV S1 仅提供 65 寸版本,售价 6999 元;OPPO TV R1 55 寸版本售价 3299 元,65 寸版本售价 4299 元。</p>\n" +
                "  <p>同时,OPPO 也在本次发布会上正式推出真无线降噪蓝牙耳机 Enco X,Enco X 搭载 DBEE 3.0 声音系统,采用同轴双单元和双麦双核设计,支持双重主动降噪以及 LHDC™ 超清无线传输协议,配合蓝牙 5.2 传输延迟最低可达 47ms,全链路传输最低延时 94ms。OPPO Enco X 售价 999 元。</p>\n" +
                "  <figure class=\"image ss-img-wrapper\">\n" +
                "   <img src=\"http://dev-img.wuanlife.com/768208215832924160.png\">\n" +
                "   <figcaption>\n" +
                "    OPPO Enco X\n" +
                "   </figcaption>\n" +
                "  </figure>\n" +
                "  <p>最后,OPPO 还推出了 OPPO Find X2 英雄联盟 S10 限定版和 OPPO Watch 英雄联盟限定版,售价分别为 4999 元和 1999 元。</p>\n" +
                "  <h2>小米公布 80W 无线快充方案</h2>\n" +
                "  <p>10 月 19 日,小米在微博上 <a href=\"https://weibo.com/2202387347/JpSAn9Fvv\">宣布</a> 无线充电技术功率突破了80W,可以在 8分钟内为 4000mAh 的电池充入一半电量,完全充满则需要 19 分钟。演示视频中的设备由小米 10 Pro 、小米 55W 风冷立式无线充电底座改造而来,输入电压达到 20V。目前,小米尚未公布何时量产。<a href=\"https://weibo.com/2202387347/JpSAn9Fvv\">来源</a></p>\n" +
                "  <figure class=\"image ss-img-wrapper\">\n" +
                "   <img src=\"http://dev-img.wuanlife.com/768208219444219904.jpg\">\n" +
                "  </figure>\n" +
                "  <h2>智能音响 Sonos Arc 国内上市,售价 7980 元</h2>\n" +
                "  <p>10 月 19 日,Sonos 官方公众号 <a href=\"https://mp.weixin.qq.com/s/8PBPj3-VAG0m2bOQ_zzeuQ\">宣布</a>,智能音响 Sonos Arc 即将在国内上市,售价 7980 元。Sonos Arc 是 Sonos 于今年 5 月发布的一款专为电视、电影、音乐和游戏等娱乐方式打造的高端智能条形音响,支持杜比全景声的立体声效,可以使用电视遥控器、Sonos S2 应用和 AirPlay 2 等进行控制。<a href=\"https://mp.weixin.qq.com/s/8PBPj3-VAG0m2bOQ_zzeuQ\">来源</a></p>\n" +
                "  <figure class=\"image ss-img-wrapper\">\n" +
                "   <img src=\"http://dev-img.wuanlife.com/768208224544493568.png\">\n" +
                "  </figure>\n" +
                "  <h2>支付宝上线「晚点付」功能</h2>\n" +
                "  <p>据 IT 之家报道,支付宝近日上线「晚点付」功能,该功能是芝麻信用分大于 700 分的用户专享,当用户在使用支付宝扫一扫或者付款码消费时,若所有支付渠道均不可用且手动选择每张银行卡均无法成功付款时便可以使用该功能先行垫付。<a href=\"https://www.ithome.com/0/514/453.htm\">来源</a></p>\n" +
                "  <h2>你可能错过的好文章</h2>\n" +
                "  <ul>\n" +
                "   <li>? <a href=\"https://sspai.com/post/63158\">智能家居新手入门(上):常见的智能家居平台、品牌和连接方式</a></li>\n" +
                "   <li>⚡️ <a href=\"https://sspai.com/post/63201\">Pixel 5 硬件不出彩?先来试试这些软件新特性</a></li>\n" +
                "   <li>? <a href=\"https://sspai.com/post/63210\">这 6 件百元小物,是本獭最近买的新玩具</a></li>\n" +
                "   <li>? <a href=\"https://sspai.com/post/63219\">派评 | 近期值得关注的 App</a></li>\n" +
                "  </ul>\n" +
                "  <p style=\"margin-left:0px;\">&gt; 下载少数派 <a href=\"https://sspai.com/page/client\">客户端</a>、关注 <a href=\"https://sspai.com/s/J71e\">少数派公众号</a>,了解每日数码新鲜事 ?</p>\n" +
                "  <p style=\"margin-left:0px;\">&gt; 特惠、好用的硬件产品,尽在 <a href=\"https://shop549593764.taobao.com/?spm=a230r.7195193.1997079397.2.2ddc7e0bPqKQHc\">少数派 sspai 官方店铺</a> ?</p>\n" +
                "  <p>© 本文著作权归作者所有,并授权少数派独家使用,未经少数派许可,不得转载使用。</p>\n" +
                " </body>\n" +
                "</html>";

        List format = HtmlTagClearUpTool2.format(html);
        System.out.println(JSONArray.toJSONString(format));
        System.out.println("");
    }

    /**
     * 格式化入口
     *
     * @param html
     * @return
     */
    public static List format(String html) {
        html = html.replaceAll("\\n", "");
        Document document = Jsoup.parse(html);
        Elements body = document.getElementsByTag("body");
        List<Node> nodes = body.get(0).childNodes();
        return HtmlTagClearUpTool2.format(nodes);
    }

    /**
     * 格式化
     *
     * @param nodes
     * @return
     */
    public static List format(List<Node> nodes) {
        ArrayList tags = new ArrayList<>();
        for (Node node : nodes) {
            //获取标签名称
            Tag tag = new Tag();
            tag.setName(node.nodeName());

            //获取标签属性
            Attrs attrs = null;
            switch (node.nodeName().toLowerCase()) {
                case "a":
                    attrs = new Attrs();
                    attrs.setHref(node.attributes().get("href"));
                    break;
                case "img":
                    attrs = new Attrs();
                    attrs.setSrc(node.attributes().get("src"));
                    if (StringUtils.isNotBlank(node.attributes().get("alt"))) {
                        attrs.setAlt(node.attributes().get("alt"));
                    } else {
                        attrs.setAlt("图片");
                    }
                    break;
                case "#text":
                    //不是一个tag,只是一串文字
                    if (StringUtils.isNotBlank(node.toString())) {
                        Value value = new Value();
                        value.setText(node.toString());
                        value.setType(node.nodeName());
                        tags.add(value);
                    }
                    continue;
                default:
            }
            tag.setAttrs(attrs);

            //获取标签的子标签
            tag.setChildren(HtmlTagClearUpTool2.format(node.childNodes()));
            tags.add(tag);
        }
        return tags;
    }

    public static String getHtmlText(Node node) {
        String string = node.toString();
        for (Node kid : node.childNodes()) {
            string = string.replaceAll(kid.toString(), "");
        }
        return HtmlTagClearUpTool2.clearUp(string, "<.*?>\"");
    }

    /**
     * 过滤html
     *
     * @param html
     * @param rule
     * @return
     */
    public static String clearUp(String html, String rule) {
        if (html == null || html.trim().length() < 1) {
            return html;
        }
        html = html.replaceAll(rule, "");
        return html;
    }

    static class Tag {
        private String name;
        private Attrs attrs;
        private List<Object> children;

        public Tag() {
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public Attrs getAttrs() {
            return attrs;
        }

        public void setAttrs(Attrs attrs) {
            this.attrs = attrs;
        }

        public List<Object> getChildren() {
            return children;
        }

        public void setChildren(List<Object> children) {
            this.children = children;
        }
    }

    static class Value {
        private String type;
        private String text;

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
        }

        public String getText() {
            return text;
        }

        public void setText(String text) {
            this.text = text;
        }
    }

    static class Attrs {
        private String alt;
        private String src;
        private String href;

        public String getAlt() {
            return alt;
        }

        public void setAlt(String alt) {
            this.alt = alt;
        }

        public String getSrc() {
            return src;
        }

        public void setSrc(String src) {
            this.src = src;
        }

        public String getHref() {
            return href;
        }

        public void setHref(String href) {
            this.href = href;
        }
    }
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值