识别出字符串中有效的数据

背景:工作中有个现场项目的需求是这样的,要求把对检索出来的返回结果格式化展示。返回结果的内容由后台C对原始数据进行读取随后发给中台Java最后返回给前端的,但是返回结果是字符串的,无法对字符串有效识别,最终数据被传到前端,如果不解析就只能看到密密麻麻的字符串。

思路

1. 寻找规律,数据格式有个特点要不就是对象,要不就是数组

let obj = {name: 'zz', age:11};
let arr = [{name: 'zz'},{age: 11}, children:[]];

这里会发现一个特点,如果是一个完整的数据,那么括号一定是匹配的,也就是一个左括号对应一个右括号组成一组数据,如果不匹配那这个数据也用不了。
2. 如何取出数据,识别数据,并保存数据

  • 图中左括号对应的右括号就能组成一组数据,那么只需要用左括号对应的下标和右括号对应的下标的区间取出就可以了
  • 那怎么判断左括号和右括号是一对呢,这里要用到一种数据结构栈,利用其先进后出的特点进行匹配

    想必大家已经知道了,对,没错,如果遇到右括号,就把存放括号的数组弹出一个字符,如果弹出的括号和当前遇到的括号匹配,就将这个括号之间的字符截取出来判断。
  • 利用json.parse()方法就能判断每一次取出的数据是否是一个JSON数据对吧
  • 取出来的是对象就一个个push进空数组就好,如果是数组呢,那就直接替换掉那个空数组吧
    这里创建一个空数组[],如果每次取出的字符串都是对象,那就push进这个数组,如果取出的数组,就替换这个创建的数组,这样一直进行下去,字符串中的所有数据会被识别一遍。

就这样一直到结束

编码

stringFormat(strData){
            strData = strData.trim();
            let bracketArr = []; // 存放括号
            let bracketIndexArr = []; // 存放括号下标
            let leftP = 0; // 左指针配合构造字符串区间
            let rightP; // 右指针一直扫描文本
            let strTotalLen = strData.length; // 文本长度
            let currBracket;  // 当前括号
            let leftBracketIndex; // 左括号下标
            let resArr = []; // 存放结果
            if(strData[0] !== '[' && strData[0] !== '{') {
                this.orgrinHtml = strData;
                console.log('orgrinHtml', strData);
                return;
            };
            // 遍历字符串文本
            for(rightP = 0; rightP < strTotalLen; rightP++) {
                // console.log(strData);
                // 如果碰到左括号入栈push,并且把下标位置也入栈
                currBracket = strData[rightP];
                leftBracketIndex = rightP;
                if(currBracket === '[' || currBracket === '{') {
                    bracketArr.push(currBracket);
                    bracketIndexArr.push(leftBracketIndex);
                } else if (currBracket === '}' || currBracket === ']') {  // 如果发现了回括,就把左括号弹出,看能不能匹配上
                    let stackTopBracket = bracketArr.pop();  // 弹出栈顶的左括号
                    if(stackTopBracket === '{' && currBracket === '}' || stackTopBracket === '[' && currBracket === ']'){
                        // 弹出栈顶下标给左指针定位,取出左右指针区间,看是否可以转成JSON数据
                        leftP = bracketIndexArr.pop();
                        let tempStr = strData.substring(leftP, rightP + 1);
                        try {
                            let strToObj = JSON.parse(tempStr);
                            if(strToObj) {
                                let type = this.checkDataType(strToObj);
                                if(type === 'object') {
                                    resArr.push(strToObj)
                                }
                                if(type === 'array') {
                                    resArr = strToObj
                                };
                            }
                        } catch (error) {
                            try {
                                if(error.name === 'SyntaxError'){
                                    let evalObj = eval('(' + tempStr + ')');
                                    let type = this.checkDataType(evalObj);
                                    if(type === 'object') {
                                        resArr.push(evalObj)
                                    }
                                    if(type === 'array') { resArr = evalObj };
                                }
                            } catch (error) {
                                console.log(error);
                            }
                        }
                    }
                }
            }
            this.dataFormat(resArr);
        }
 // 判断数据类型
checkDataType(data){
	let type = Object.prototype.toString.call(data);
	if(type === '[object Object]') {
		type = 'object';
	}else if(type === '[object Array]') {
		type = 'array';
	}
	return type;
}

总结

1、字符串处理的时候要取出某段数据可以用“滑动窗口”的思想,左右指针(下标)构造出字符串区间,这里的下标数组取出的下标位置就是左指针的位置。
2、结合栈的数据结构先进后出的特点,栈顶元元素始终是最后push进去的,将栈顶元素和指定元素进行匹配
3、JSON.parse方法判断是否是合法数据,如果是就存起来
以上,如有不足或是更好的建议,欢迎留言。

posted @ 2022-03-08 09:44  rangze  阅读(125)  评论(0)    收藏  举报