关于解析器:自己动手写json解析器0x02分词清洗

32次阅读

共计 2914 个字符,预计需要花费 8 分钟才能阅读完成。

介绍

在上一节中,咱们介绍了如何对 json 进行分词,并且胜利对示例 json 进行了分词,这一节咱们介绍如何对分词进行荡涤,可能荡涤这个词用的不是很精确,然而我也不晓得业余叫法叫啥,有晓得的同学心愿在评论区留言,分词荡涤的目标就是将 tokens 进行整顿,去掉一些没用的,而后进行一些整合便于后续的剖析,有点像大数据里的数据荡涤将脏数据荡涤为能被业务所用的高质量数据,所以这里用了分词荡涤这个词。

分词荡涤

介绍

为了便于前面步骤的解决,咱们这里须要对分词进行荡涤,荡涤后的分词列表能够满足以下要求

  • 第一节中字符串都是当作 type=string 解决,通过荡涤后,能够辨别 key 和 value
  • 如果实现了 key-value 的荡涤,那么 kvSymbol 就不须要了,后续也不须要用到这个 token,能够从列表中移除

实现

以下是具体实现的代码

/**
 * token 荡涤
 * 辨别 key 和 value 的 token
 *
 * @param originTokens 原始 token 列表
 * @return 荡涤过的 token 列表
 */
public List<Token> tokenClean(List<Token> originTokens) {jsonTokens = new ArrayList<>();
    int tokenIndex = 0;
    while (tokenIndex < originTokens.size()) {Token token = originTokens.get(tokenIndex);
        if ("string".equals(token.getType())) {if (tokenIndex + 1 < originTokens.size() &&
                    "kvSymbol".equals(originTokens.get(tokenIndex + 1).getType())) {token.setType("key");
                jsonTokens.add(token);
                Token valueToken = originTokens.get(tokenIndex + 2);
                //object 和 array 类型临时不设置 value 类型
                if (!"object".equals(valueToken.getType()) && !"array".equals(valueToken.getType())) {valueToken.setType("value");
                }
                jsonTokens.add(valueToken);
                // 因为读取了 kvSymbol 和 value 两个 token 因而要 +2
                tokenIndex += 2;
            } else {
                // 如果没有 kvSymbol 间接当作 value 进行解决
                token.setType("value");
                jsonTokens.add(token);
            }
        } else {
            // 荡涤目前只解决 string 类型其余类型疏忽
            jsonTokens.add(token);
        }
        ++tokenIndex;
    }
    return jsonTokens;
}

测试

咱们应用示例 json 进行测试

public class Main {public static void main(String[] args) throws Exception {InputStream fin = Main.class.getResourceAsStream("/example.json");
        byte[] buf = new byte[fin.available()];
        fin.read(buf);
        fin.close();
        String json = new String(buf, "utf-8");
        JSONParser parser = new JSONParser();
        List<Token> tokens = parser.tokenizer(json);
        tokens = parser.tokenClean(tokens);
        System.out.println(String.format("|%-12s|%-12s|%-15s|", "type", "valueType", "value"));
        System.out.println("-------------------------------------------");
        for (Token t : tokens) {
            System.out.println(String.format("|%-12s|%-12s|%-15s|",
                    t.getType(),
                    t.getValueType(),
                    t.getValue()));
        }
        System.out.println("-------------------------------------------");
    }
}

后果如下:

|type        |valueType   |value          |
-------------------------------------------
|object      |object      |{              |
|key         |string      |name           |
|value       |string      |asan           |
|key         |string      |age            |
|value       |long        |32             |
|key         |string      |married        |
|value       |bool        |true           |
|key         |string      |birthday       |
|value       |string      |1992-02-08     |
|key         |string      |salary         |
|value       |float       |1234.56        |
|key         |string      |description    |
|value       |string      |a "hudsom" man |
|key         |string      |tags           |
|array       |array       |[              |
|value       |string      |coder          |
|value       |string      |mid-age        |
|array       |array       |]              |
|key         |string      |location       |
|object      |object      |{              |
|key         |string      |province       |
|value       |string      | 福建省          |
|key         |string      |city           |
|value       |string      | 泉州市          |
|key         |string      |area           |
|value       |string      | 晋江市          |
|object      |object      |}              |
|key         |string      |family         |
|array       |array       |[              |
|object      |object      |{              |
|key         |string      |relation       |
|value       |string      |couple         |
|key         |string      |name           |
|value       |string      |Helen          |
|object      |object      |}              |
|object      |object      |{              |
|key         |string      |relation       |
|value       |string      |daughter       |
|key         |string      |name           |
|value       |string      |XiaoMan        |
|object      |object      |}              |
|array       |array       |]              |
|object      |object      |}              |
-------------------------------------------

和荡涤前相比,没有了 kvSymbol 并且胜利辨别了 key 和 value 类型

代码

残缺代码请参考我的项目 https://github.com/wls1036/tiny-json-parser 的 0x02 分支

正文完
 0