在一段混合文本中提取json对象

提出问题

假设有这样一段文本,里面混入了一些json字符串,我们需要把json字符串提取出来。网上大部分解决方案是正则表达式/{.*?}/,但是正则的方法有很多局限性。比如下文这个例子,如果正则使用非贪婪模式,匹配会在"alice"后面的第一个"}"停下来,如果开启贪婪模式,则会把两个json当作一个。

sql 复制代码
Some text before {"key1":"value1","key2":{"alice":"alice"},"key3":{"bob":"bob"}} some text in between {"key4":"value4"} some text after.

解决

我查了Google和ChatGPT,都没有一个现成的解决方案。看来只能发挥自己动手丰衣足食的精神了。

这个问题其实非常经典的栈数据结构的应用题,就是判断括号是否匹配的问题。如果前面有两个左括号,后面必须有两个右括号,才是完整的。那我们就实现一下。

java 复制代码
    /**
     * 提取json信息
     * 
     * @param content
     * @return
     */
    protected static List<String> extractJson(String mixedContent) {
        List<String> result = new ArrayList<>();
        Stack<Integer> stack = new Stack<>();
        Boolean slash = false;
        for (int i = 0; i < mixedContent.length(); i++) {
            if (slash) {
                // 忽略所有的转义字符
                slash = false;
                continue;
            }
            if (mixedContent.charAt(i) == '{') {
                stack.push(i);
            } else if (mixedContent.charAt(i) == '}') {
                if (stack.isEmpty()) {
                    // System.out.println("没有对应的开括号,位置:" + i);
                    continue;
                }
                int start = stack.pop();
                String json = mixedContent.substring(start, i + 1);
                if (stack.size() == 0) {
                    result.add(json);
                }
            } else if (mixedContent.charAt(i) == '\') {
                slash = true;
            }
        }
        // if (!stack.isEmpty()) {
        // System.out.println("没有对应的闭括号,位置:" + stack.pop());
        // }
        return result;
    }

因为我的场景都是json对象,都是从"{"开始的,因此我只处理了花括号{},至于花括号内部是否是一个正确的 json的问题,交给后续的 json 解析库去处理。

因为我只需要提取合法的部分,所以这里的两个报错信息被我注释掉了,如果需要严格的判断可以处理这两个错误信息。

同时简单处理了转义字符。因为他无关我们的闭合检查,所以直接忽略掉。

这段代码对我当前的需求算够用的,想完美一点,并且支持更多场景的话,可以继续补充完善,比如可以把\[\]和双引号也考虑进来,原理是一样的。

应用

这个业务场景是我需要设计一个 word 填充模版,填充项有各种类型,比如单选、日期、纯文本、富文本等等。我需要从 word 中解析出这些被填充项作为表单给到前端去填写,因为这样可以避免格式问题,从而有更好的交互体验。填写完之后,还需要把前端表单的内容填充进 word 模板并导出。

我使用了 json 来定义我的填充项,所以需要解决从段落中解析出所有 json 对象的场景。下面是完整的解决方案代码,放在 github,欢迎大家提出宝贵意见。

github.com/yszc/office...

相关推荐
Dream it possible!3 小时前
LeetCode 面试经典 150_多维动态规划_交错字符串(97_C++_中等)
算法·leetcode·面试·动态规划
心抵鹊3 小时前
算法之双指针系列(一)
算法·leetcode
十二4 小时前
【洛谷题解】P1083 [NOIP 2012 提高组] 借教室(二分答案 + 差分)
数据结构·c++·算法·蓝桥杯
小此方5 小时前
[算法实战论:动态规划]回文串问题的dp解法,回文串问题的母题,以及以此为基础的派生题
算法·动态规划
Pniubi5 小时前
力扣560.和为k的子数组
算法·leetcode·职场和发展
miofly5 小时前
百度开源ERNIE 5.5 Flash Base,总参数280B仅激活14B
开源·github
D e re k ZH6 小时前
C++ 从零入门(一):基础语法与程序结构
数据结构·c++·算法
Pniubi6 小时前
力扣438.找到字符串中所有字母异位词
算法·leetcode·职场和发展
dong_junshuai6 小时前
每天一个开源项目#154 Nushell:结构化管道怎样跨过文本边界
github
東隅已逝,桑榆非晚9 小时前
算法6. 双指针法-查找总价格为目标的两个商品
c++·学习·算法