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 = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
// :[
// ,[
const rx_four = /(?:^|:|,)(?:\s*\[)+/g;
// 一些符号的unicode表示法
const rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\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 });
js jsonParse的更多相关文章
- 原生js封装dom操作库
var utils = (function(window) { var flag = "getComputedStyle" in window; function win(attr ...
- JS操作JSON常用方法
一.JSON字符串的替换 工作经常遇到这样的字符串,如下: 需要经过替换后,才能从字符串转化成JSON对象.这里我们需要用JS实现replaceAll的功能, 将所有的 ' \\" ' 替换 ...
- 【JavaScript】使用纯JS实现多张图片的懒加载(附源码)
一.效果图如下 上面的效果图,效果需求如下 1.还没加载图片的时候,默认显示加载图片背景图 2.刚开始进入页面,自动加载第一屏幕的图片 3.下拉界面,当一张图片容器完全显露出屏幕,即刻加载图片,替换背 ...
- json代码——json序列化,json-parse,JSONstringify格式化输出,虚拟DOM
JS对象转为类似json的字符串,对象->字符串叫序列化,字符串->对象 是反序列化 ㈠json序列化 <script> var shy = new Object() ...
- 在 Node.js 中处理大 JSON 文件
在 Node.js 中处理大 JSON 文件 场景描述 问题一: 假设现在有一个场景,有一个大的 JSON 文件,需要读取每一条数据经过处理之后输出到一个文件或生成报表数据,怎么能够流式的每次读取一条 ...
- Node.js精进(3)——流
在 JavaScript 中,一般只处理字符串层面的数据,但是在 Node.js 中,需要处理网络.文件等二进制数据. 由此,引入了Buffer和Stream的概念,两者都是字节层面的操作. Buff ...
- Vue.js 和 MVVM 小细节
MVVM 是Model-View-ViewModel 的缩写,它是一种基于前端开发的架构模式,其核心是提供对View 和 ViewModel 的双向数据绑定,这使得ViewModel 的状态改变可以自 ...
- js学习笔记:操作iframe
iframe可以说是比较老得话题了,而且网上也基本上在说少用iframe,其原因大致为:堵塞页面加载.安全问题.兼容性问题.搜索引擎抓取不到等等,不过相对于这些缺点,iframe的优点更牛,跨域请求. ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
随机推荐
- 关于js中each()使用return不能终止循环
Jquery的each里面用return false代替break:return ture代替continue $(xx).each(function() { if(xx){ return false ...
- Shiro中Subject对象的创建与绑定流程分析
我们在平常使用Shrio进行身份认证时,经常通过获取Subject 对象中保存的Session.Principal等信息,来获取认证用户的信息,也就是说Shiro会把认证后的用户信息保存在Subjec ...
- 洛谷P4180
被教练安排讲题 可恶 这道题我是十月初上课时花了一下午做出来的,当时连倍增都不会,过程比较困难,现在看看还可以 本来想口胡一发,后来想了想可能以后要用,还是写成文章吧 Description 求一棵严 ...
- 图文并茂-超详解 CS:APP: Lab3-Attack(附带栈帧分析)
CS:APP:Lab3-ATTACK 0. 环境要求 关于环境已经在lab1里配置过了.lab1的连接如下 实验的下载地址如下 说明文档如下 http://csapp.cs.cmu.edu/3e/at ...
- Oracle数据库之——分组查询,子查询及添加,更新,删除
分组查询 写的顺序: select...from...where... group by...having...order by... 执行顺序: from...where...group by... ...
- H3C交换机堆叠
(1) 配置Device A# 将用作IRF物理端口的Ten-GigabitEthernet1/0/1-Ten-GigabitEthernet1/0/4的手工关闭.使用端口批量配置功能可以更 ...
- .Net Core 3.1浏览器后端服务(一) Web API项目搭建
一.前言 基于CefSharp开发的浏览器项目已有一段时间,考虑到后期数据维护需要Server端来管理,故开启新篇章搭建浏览器后端服务.该项目前期以梳理服务端知识为主,后期将配合CefSharp浏览器 ...
- Pytest(17)运行未提交的git(pytest-picked)
前言 我们每天写完自动化用例后都会提交到 git 仓库,随着用例的增多,为了保证仓库代码的干净,当有用例新增的时候,我们希望只运行新增的未提交 git 仓库的用例.pytest-picked 插件可以 ...
- Codeforces Round #428 (Div. 2) C. Journey (简单搜索)
题意:给你一颗树(边是无向的),从根节点向下走,统计走到每个子节点的概率,求所有叶子节点的深度乘上概率的和. 题解:每层子节点的概率等于上一层节点的概率乘\(1\)除以这层的子节点数,所以我们用\(d ...
- 编译安装MySQL 5.5.33
环境要求: 主机名 IP地址 需要软件及版本 系统版本 mysql.mfyxw.com 192.168.80.135 Mysql5.5.33 5.5.33 1.设定主机名 hostnamectl se ...