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 });
    
  • 相关阅读:
    dba_segments和dba_tables的不同
    查询用户表空间
    远程登录Oracle数据库
    SQL Server 收缩数据库
    Xshell乱码解决方法设置
    Spring常用注解
    Hibernate的fetch
    在 Eclipse 中使用 JSHint 检查 JavaScript 代码
    enterprise architect (EA) 源码生成UML类图,帮助理解项目工程
    上传excel数据到数据库中
  • 原文地址:https://www.cnblogs.com/ajanuw/p/12372128.html
Copyright © 2011-2022 走看看