使用Parsimmon解析JavaScript中用户输入的数组
用Parsimmon解析带嵌套结构的用户输入数组
你选Parsimmon来处理这类包含嵌套数组、数字、字符串的用户输入真的太合适了!它的声明式解析规则特别适合构建这种需要处理复杂嵌套结构的自定义解析器,官方给出的JSON解析示例刚好可以直接拿来用(或者做小调整)来满足你的需求。
先给你补全那段你提到的不完整的JSON解析器代码,这个完整版本已经能完美处理你给出的输入:
const P = require('parsimmon'); // 先定义一个空白符解析器,用来忽略输入中的空格、换行、制表符等 const whitespace = P.regex(/\s*/); const JSONParser = P.createLanguage({ // 主入口:可以解析任意JSON值(对象、数组、字符串、数字等) value: r => P.alt(r.object, r.array, r.string, r.number, r.null, r.true, r.false) .thru(parser => whitespace.then(parser)), // 解析JSON对象 object: r => P.string('{') .then(whitespace) .then(r.pair.sepBy(whitespace.then(',').then(whitespace))) .skip(whitespace) .skip(P.string('}')) .map(pairs => pairs.reduce((obj, [key, val]) => { obj[key] = val; return obj; }, {})), // 解析对象中的键值对 pair: r => r.string.skip(whitespace).skip(':').skip(whitespace).then(r.value), // 核心:解析JSON数组(就是你需要的部分) array: r => P.string('[') .then(whitespace) .then(r.value.sepBy(whitespace.then(',').then(whitespace))) .skip(whitespace) .skip(P.string(']')), // 解析双引号包裹的字符串 string: () => P.regex(/"(?:\\.|[^"])*"/).map(str => str.slice(1, -1)), // 解析数字(支持整数、小数、科学计数法) number: () => P.regex(/-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?/).map(Number), // 解析null null: () => P.string('null').map(() => null), // 解析true true: () => P.string('true').map(() => true), // 解析false false: () => P.string('false').map(() => false), });
使用的时候非常简单,直接调用解析器的对应方法就行:
// 你的测试输入 const userInput = '[1, 2, 3, 4, [1, 2, 3], "test", "test hello"]'; // 如果只想解析数组,直接用array规则 const parsedArray = JSONParser.array.parse(userInput); console.log(parsedArray); // 输出结果:[1, 2, 3, 4, [1, 2, 3], 'test', 'test hello'] // 如果需要解析任意JSON值(比如输入可能是对象或数组),用value规则 const parsedValue = JSONParser.value.parse(userInput);
如果你的用户输入有一些非标准JSON的情况(比如用单引号包裹字符串),也可以很轻松地修改string规则来适配:
// 修改为支持单引号字符串 string: () => P.regex(/'(?:\\.|[^'])*'/).map(str => str.slice(1, -1)) // 或者同时支持单双引号 string: () => P.alt( P.regex(/"(?:\\.|[^"])*"/), P.regex(/'(?:\\.|[^'])*'/) ).map(str => str.slice(1, -1))
Parsimmon的好处就是规则可以灵活组合,你完全可以根据自己的需求增减或修改解析规则,比如如果不需要解析对象、布尔值或null,直接从value的alt里去掉对应的规则就行。
内容的提问来源于stack exchange,提问作者Marin
相关产品推荐
相关产品推荐

