当前位置: 移动技术网 > IT编程>开发语言>JavaScript > 记一次解析字符串:在目标字符串中找出指定的N个字符串所在的起始位置

记一次解析字符串:在目标字符串中找出指定的N个字符串所在的起始位置

2020年03月29日  | 移动技术网IT编程  | 我要评论
我们的项目上有一个这样的场景:一个下拉选择框,同时要支持用户输入,将最终的结果显示在文本框中(就是普通的字符串,用户在下拉框中选择的放在【】中)……不知道能不能想象出来,写上一篇笔记的时候发现和咱们博客园选择“tag 标签”的功能有点接近啊,我们的ui还是跟她有些不同。 还是拿一个具体的例子说一下吧 ...

  我们的项目上有一个这样的场景:一个下拉选择框,同时要支持用户输入,将最终的结果显示在文本框中(就是普通的字符串,用户在下拉框中选择的放在【】中)……不知道能不能想象出来,写上一篇笔记的时候发现和咱们博客园选择“tag 标签”的功能有点接近啊,我们的ui还是跟她有些不同。

  还是拿一个具体的例子说一下吧。下拉框中有“姓名”、“年龄”两个选择项,你可以选择也可以自己在文本框中输入,例如文本框中的内容是:自定义001【姓名】自定义002【年龄】自定义003。我们要做的就是解析这个字符串,我们需要识别出其中的“姓名”和“年龄”(无论是用户选择的,还是用户输入的),最后的结果应该是这样的 ["自定义001","【姓名】","自定义002","【年龄】","自定义003"]。

  这里还要在补充一点他们的要求:就是可以同时匹配多个时候(开始的索引位置相同,但是结尾不同),我们需要识别下拉列表中的第一个。有点抽象,还是说一个例子吧。这里下拉列表中有“姓名】”和“姓名”两个,这时候文本框中的内容是:自定义001【姓名】】自定义002。交换下拉列表中的顺序,最终得到的结果是不一样的。

  说了这么一大推,感觉好没意思啊!其实还是蛮有意思的(解析这个)。遇到这个问题之后最先想到的就是,遍历下拉框数组,利用indexof查找看看有没有,之后截取三部分(前面的、自己、后面的),之后递归处理前面和后面的部分。我去,想着简单但是写的时候好费劲啊!最后查了一下,看看有没有这种方法,在目标字符串中找出指定的n个字符串的所在起始位置,一个方法可以搞定的那种,最后还是正则表达式救了我。现在我可以得到下拉选项中的每一项在目标字符串的起始位置了,剩下的就是利用这些起始位置去截取目标字符串了,脑袋一热将这些这些索引位置放到一个数组中(去重),之后排序,之后两两已截取不就完了,这样写完之后就真的凉凉了,很多字符串都解析错误,之后弄了好几版都不行,决定静下来分析一下,看看到底有多少种情况。之前竟然还想到数据去重(确实是第一次写就去重了),但是就没有想想什么情况下有重复的情况出现:索引开始相同,某一个的索引结束是另一个的开始……后来我直接画图了,列出了12中情况,在下面可以在纸上画,这里呢?我也又找到了一个神器:,你看一下:

  一共有12中情况,要是一个一个if else 太费劲了,细看一下发现中间的8种情况是有问题的,如果将这8种情况下的起始索引都放到数组中去截取字串,那么他就会将下拉框中的下拉项(也就是图中两个中的一个截断),所以呢用了一下排除法。之后呢,为了验证我也列举了上面的6中情况(下面分别给出例子),感觉前面的6个和后面的6个是对称的……

//    参考:
//        https://developer.mozilla.org/zh-cn/docs/web/javascript/reference/global_objects/regexp/@@matchall
//        https://developer.mozilla.org/zh-cn/docs/web/javascript/reference/global_objects/string/matchall
//    待选列表(下拉列表项)
var tobeselectedlist = [{
        dispalyname: "姓名",
        dispalyindex: "name1"
    }, {
        dispalyname: "年龄",
        dispalyindex: "age"
    }, {
        dispalyname: "姓【名",
        dispalyindex: "name2"
    }, {
        dispalyname: "名】001",
        dispalyindex: "name3"
    }, {
        dispalyname: "【姓名",
        dispalyindex: "name4"
    }, {
        dispalyname: "1【姓名】1",
        dispalyindex: "name5"
    }, {
        dispalyname: "姓名】",
        dispalyindex: "name6"
    }
];
var tempdispalynamearr = tobeselectedlist.map(function (item) {
        return item.dispalyname;
    });

//    解析方法
var gettargetarrbyuserinputandfilterstrs = function (userinputstr, filterstrs) {
    var tempindexposarr = [],
    tempindexposobjarr = [],
    tempfilterstraddcharobj = {};
    filterstrs.foreach(function (filterstr, index) {
        var tempkey = '【' + filterstr + '】',
        tempregexp = new regexp(tempkey, 'g'),
        match;
        tempfilterstraddcharobj[tempkey] = filterstr;
        while ((match = tempregexp.exec(userinputstr)) !== null) {
            var tempfilterposarrs = tempindexposobjarr.filter(function (startandlastindexitem) {
                    // return (match.index >= startandlastindexitem.index && match.index < startandlastindexitem.lastindex) ||
                    // (match.index < startandlastindexitem.index && tempregexp.lastindex >= startandlastindexitem.lastindex);
                    return !(tempregexp.lastindex <= startandlastindexitem.index || match.index >= startandlastindexitem.lastindex);
                });
            if (tempfilterposarrs.length === 0) {
                tempindexposobjarr.push({
                    index: match.index,
                    lastindex: tempregexp.lastindex
                });
            }
        }
    });
    tempindexposobjarr.foreach(function (indexobj) {
        if (tempindexposarr.indexof(indexobj.index) < 0) {
            tempindexposarr.push(indexobj.index);
        }
        if (tempindexposarr.indexof(indexobj.lastindex) < 0) {
            tempindexposarr.push(indexobj.lastindex);
        }
    });
    if (tempindexposarr.indexof(0) < 0) {
        tempindexposarr.push(0);
    }
    if (tempindexposarr.indexof(userinputstr.length) < 0) {
        tempindexposarr.push(userinputstr.length);
    }
    tempindexposarr = tempindexposarr.sort(function (a, b) {
            return a - b;
        });

    var lastneedarr = [];
    tempindexposarr.foreach(function (posindex, index) {
        if (index < tempindexposarr.length - 1) {
            var tempisonefilterstr = userinputstr.substring(posindex, tempindexposarr[index + 1]);
            // if(tempfilterstraddcharobj.hasownproperty(tempisonefilterstr)){
            // tempisonefilterstr=tempfilterstraddcharobj[tempisonefilterstr]
            // }
            lastneedarr.push(tempisonefilterstr);
        }
    });
    return lastneedarr;
};
//    等待解析的字符串(也就是用户选择或者输入的最终结果)

var waitanalysisstr1 = "自定义001【姓名】自定义002【年龄】自定义003";
var tobeselectedlist1_1 = ["姓名", "年龄"]; //    ["自定义001","【姓名】","自定义002","【年龄】","自定义003"]
var tobeselectedlist1_2 = ["年龄", "姓名"]; //    ["自定义001","【姓名】","自定义002","【年龄】","自定义003"]

var waitanalysisstr2 = "自定义001【姓名】【年龄】自定义002";
var tobeselectedlist2_1 = ["姓名", "年龄"]; //    ["自定义001","【姓名】","【年龄】","自定义002"]
var tobeselectedlist2_2 = ["年龄", "姓名"]; //    ["自定义001","【姓名】","【年龄】","自定义002"]

var waitanalysisstr3 = "自定义001【姓【名】001】自定义002";
var tobeselectedlist3_1 = ["姓【名", "名】001"]; //    ["自定义001","【姓【名】","001】自定义002"]
var tobeselectedlist3_2 = ["名】001", "姓【名"]; //    ["自定义001【姓","【名】001】","自定义002"]  

var waitanalysisstr4 = "自定义001【【姓名】自定义002"; //    【姓名 、 姓名    交换顺序试试
var tobeselectedlist4_1 = ["【姓名", "姓名"]; //    ["自定义001","【【姓名】","自定义002"]
var tobeselectedlist4_2 = ["姓名", "【姓名"]; //    ["自定义001【","【姓名】","自定义002"]

var waitanalysisstr5 = "自定义001【1【姓名】1】自定义002"; //    1【姓名】1 、 姓名    交换顺序试试
var tobeselectedlist5_1 = ["1【姓名】1", "姓名"]; //    ["自定义001","【1【姓名】1】","自定义002"]
var tobeselectedlist5_2 = ["姓名", "1【姓名】1"]; //    ["自定义001【1","【姓名】","1】自定义002"]

var waitanalysisstr6 = "自定义001【姓名】】自定义002"; //    姓名 、 姓名】    交换顺序试试
var tobeselectedlist6_1 = ["姓名】", "姓名"]; //    ["自定义001","【姓名】】","自定义002"]
var tobeselectedlist6_2 = ["姓名", "姓名】"]; //    ["自定义001","【姓名】","】自定义002"]

var temptargetarr1_1 = gettargetarrbyuserinputandfilterstrs(waitanalysisstr1, tobeselectedlist1_1);
console.log(json.stringify(temptargetarr1_1));
var temptargetarr1_2 = gettargetarrbyuserinputandfilterstrs(waitanalysisstr1, tobeselectedlist1_2);
console.log(json.stringify(temptargetarr1_2));

var temptargetarr2_1 = gettargetarrbyuserinputandfilterstrs(waitanalysisstr2, tobeselectedlist2_1);
console.log(json.stringify(temptargetarr2_1));
var temptargetarr2_2 = gettargetarrbyuserinputandfilterstrs(waitanalysisstr2, tobeselectedlist2_2);
console.log(json.stringify(temptargetarr2_2));

var temptargetarr3_1 = gettargetarrbyuserinputandfilterstrs(waitanalysisstr3, tobeselectedlist3_1);
console.log(json.stringify(temptargetarr3_1));
var temptargetarr3_2 = gettargetarrbyuserinputandfilterstrs(waitanalysisstr3, tobeselectedlist3_2);
console.log(json.stringify(temptargetarr3_2));

var temptargetarr4_1 = gettargetarrbyuserinputandfilterstrs(waitanalysisstr4, tobeselectedlist4_1);
console.log(json.stringify(temptargetarr4_1));
var temptargetarr4_2 = gettargetarrbyuserinputandfilterstrs(waitanalysisstr4, tobeselectedlist4_2);
console.log(json.stringify(temptargetarr4_2));

var temptargetarr5_1 = gettargetarrbyuserinputandfilterstrs(waitanalysisstr5, tobeselectedlist5_1);
console.log(json.stringify(temptargetarr5_1));
var temptargetarr5_2 = gettargetarrbyuserinputandfilterstrs(waitanalysisstr5, tobeselectedlist5_2);
console.log(json.stringify(temptargetarr5_2));

var temptargetarr6_1 = gettargetarrbyuserinputandfilterstrs(waitanalysisstr6, tobeselectedlist6_1);
console.log(json.stringify(temptargetarr6_1));
var temptargetarr6_2 = gettargetarrbyuserinputandfilterstrs(waitanalysisstr6, tobeselectedlist6_2);
console.log(json.stringify(temptargetarr6_2));

  其实到现在,都不知道现在的算法是不是包住了所有情况,虽然下面的例子都测试通过了,还是等着真正的测试人员去测试吧!如果哪位大神有更好的方法请赐教,谢谢!

 

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网