zoukankan      html  css  js  c++  java
  • js jsonParse

    const rx_one = /^[],:{}s]*$/;
    const rx_two = /\(?:["\/bfnrt]|u[0-9a-fA-F]{4})/g;
    
    // 匹配合法json符号
    // "asd" or 1.23 or 1.3e4 or 1.3e-4 or 1.3e+4 or -10 之类的
    const rx_three = /"[^"\
    
    ]*"|true|false|null|-?d+(?:.d*)?(?:[eE][+-]?d+)?/g;
    
    // :[
    // ,[
    const rx_four = /(?:^|:|,)(?:s*[)+/g;
    
    // 一些符号的unicode表示法
    const rx_dangerous = /[u0000u00adu0600-u0604u070fu17b4u17b5u200c-u200fu2028-u202fu2060-u206fufeffufff0-uffff]/g;
    
    export function jsonParse(text: string, reviver?: Function): any {
      // 接受一个文本和一个可选的reviver函数,然后返回
      // 如果文本是有效的JSON文本,则为JavaScript值
    
      let j;
      function walk(holder: any, key: any) {
        // walk方法用于递归遍历结果结构,因此可以进行修改。
        let k: string | number;
        let v: any;
        let value = holder[key];
        if (value && typeof value === "object") {
          // {} or []
          for (k in value) {
            if (Object.prototype.hasOwnProperty.call(value, k)) {
              v = walk(value, k);
              if (v !== undefined) {
                value[k] = v;
              } else {
                delete value[k];
              }
            }
          }
          return reviver?.call(holder, key, value);
        }
      }
    
      // 解析分为四个阶段。 在第一阶段,我们替换某些
      // 具有转义序列的Unicode字符。 JavaScript处理许多字符
      // 错误地将其静默删除,或将其视为行尾。
      text = String(text);
    
      rx_dangerous.lastIndex = 0;
      if (rx_dangerous.test(text)) {
        // 转义序列的Unicode字符
        text = text.replace(rx_dangerous, function(match) {
          return "\u" + ("0000" + match.charCodeAt(0).toString(16)).slice(-4);
        });
      }
    
      // 在第二阶段,我们针对看起来像正则表达式的文本
      // 用于非JSON模式。 我们特别关注"()"和"new"
      // 因为它们会引起调用,而"="则可能导致突变
      // 但是为了安全起见,我们要拒绝所有意外的形式。
    
      // 为了解决此问题,我们将第二阶段分为4个正则表达式操作
      // 严重影响IE和Safari的regexp引擎的效率低下。 首先我们
      // 将JSON反斜杠对替换为"@"(非JSON字符)。 第二,我们
      // 用"]"字符替换所有简单值标记。 第三,我们删除所有
      // 用冒号或逗号或文本开头的方括号。 最后,
      // 我们希望看到其余字符只是空格或"]"或
      // "."或":"或"{"或"}". 如果是这样,那么该文本对于eval是安全的。
    
      if (
        rx_one.test(
          /*`{"name": "ajanuw"}` => `{]: ]}` */
          text
            .replace(rx_two, "@")
            .replace(rx_three, "]")
            .replace(rx_four, "")
        )
      ) {
        // 在第三阶段,我们使用eval函数将文本编译为
        // JavaScript结构。 "{"运算符存在句法歧义
        // 在JavaScript中:它可以开始一个块或一个对象文字。 我们包装文字
        // 尽可能消除歧义
        j = eval(`(${text})`);
    
        // 在可选的第四阶段,我们递归遍历新结构,
        // 每个名称/值对到reviver函数进行可能的转换
        return typeof reviver === "function"
          ? walk(
              {
                "": j
              },
              ""
            )
          : j;
      }
      // 如果文本不是JSON可解析的,则抛出SyntaxError。
      throw new SyntaxError("json parse error!!");
    }
    
    const r = jsonParse(`{"name": "ajanuw"}`);
    console.log({ result: r });
    
  • 相关阅读:
    PAT 甲级 1132 Cut Integer (20 分)
    AcWing 7.混合背包问题
    AcWing 9. 分组背包问题
    AcWing 5. 多重背包问题 II
    AcWing 3. 完全背包问题
    AcWing 4. 多重背包问题
    AcWing 2. 01背包问题
    AcWing 875. 快速幂
    AcWing 874. 筛法求欧拉函数
    AcWing 873. 欧拉函数
  • 原文地址:https://www.cnblogs.com/ajanuw/p/12372128.html
Copyright © 2011-2022 走看看