前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >linkedList实现高亮逻辑

linkedList实现高亮逻辑

作者头像
阿超
发布2022-08-21 15:01:05
3380
发布2022-08-21 15:01:05
举报
文章被收录于专栏:快乐阿超快乐阿超

这里是基于hutooldfa查找法得到的结果集进行封装,不一定非要依赖hutool,可以自定义FoundWord对象,里面就只用到了一个起始下标,以及对应需要高亮的词汇

代码语言:javascript
复制
public static String highlight(String text, List<FoundWord> fondWords, UnaryOperator<String> highlightOperator) {
        return highlight(text, fondWords, highlightOperator, false);
    }

    public static String highlight(String text, List<FoundWord> fondWords, UnaryOperator<String> highlightOperator, boolean needSort) {
        if (CollUtil.isEmpty(fondWords)) {
            return text;
        }
        if (needSort) {
            fondWords = Steam.of(fondWords)
                    .sorted(Comparator.comparing(FoundWord::getStartIndex)
                            .thenComparingInt(w -> w.getFoundWord().length()))
                    .toList();
        }
        LinkedList<FoundWord> linkedList = new LinkedList<>();
        // 记录历史下标(当前拼接到整体string的哪个位置了)
        int lastIdx = 0;
        // 进行遍历所有结果(理论上已按照 startIndex和fondWord.length排序)
        for (int i = 0; i < fondWords.size(); i++) {
            FoundWord fondWord = fondWords.get(i);
            String word = null;
            // 如果本次匹配发现历史下标已经超过了当前匹配值,说明这次词语和上次词语下标重复或者是上次的一部分
            if (i > 0 && lastIdx > fondWord.getStartIndex()) {
                // 移除拼接的额外部分
                FoundWord last = Objects.requireNonNull(linkedList.pollLast());
                // 判断上次和这次的长度,如果上次长度大于这次长度,说明这次词语是上次的一部分
                lastIdx -= last.getWord().length();
                if (last.getWord().length() > fondWord.getWord().length()) {
                    // 直接使用上次的词汇以及重置历史下标
                    word = last.getWord();
                }
            } else {
                // 否则根据历史下标到当前词汇下标进行查找额外部分
                String partOne = text.substring(lastIdx, fondWord.getStartIndex());
                // 并且将历史下标往前推进
                lastIdx += partOne.length();
                // 将额外部分拼接到链表中
                linkedList.add(new FoundWord(partOne, partOne, lastIdx, -1));
            }
            // 获取本次需要高亮的词汇
            word = Opt.ofNullable(word).orElseGet(fondWord::getWord);
            // 历史下标往前推进
            lastIdx += word.length();
            // 执行高亮操作
            linkedList.add(new FoundWord(word, highlightOperator.apply(word), lastIdx, lastIdx + word.length()));
        }
        // 别忘了加上最后一截
        linkedList.add(new FoundWord(text.substring(lastIdx), text.substring(lastIdx), lastIdx, lastIdx + text.substring(lastIdx).length()));
        return Steam.of(linkedList).map(FoundWord::getFoundWord).join();
    }

使用:

代码语言:javascript
复制
WordTree tree = new WordTree();
tree.addWord("大");
tree.addWord("大土豆");
tree.addWord("土豆");
tree.addWord("刚出锅");
tree.addWord("出锅");
String text = "我有一颗大土豆,刚出锅的";
List<FoundWord> foundWords = tree.matchAllWords(text, -1, true, true);
String result = CommonUtils.highlight(text, foundWords, s -> "<span style='color:red'>" + s + "</span>");
System.out.println(result);

效果:

image-20220801130912146
image-20220801130912146

这里重载了一个needSort,如果是自定义的FoundWord,需要指定为true,手动进行排序

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-08-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档