匹配括号( ( ),{ },[ ]等左右对应的字符 ) 的一种方法

来源:互联网 发布:酷方 知乎 编辑:程序博客网 时间:2024/06/11 02:09

前两天写那个异步函数顺序执行的过程中,动态修改函数,遇到setTimeout,我需要提取执行的时间,形如:

    setTimeout(function() {        output.innerText += '第三个异步函数,延迟1秒执行\n';    }, 1000);

要截取1000这个值。经过分析,我发现setTimeout()这个函数闭合的圆括号)与前一个逗号,之间的内容,就是要截取的值。

代码

想了想,要确定闭合括号)的位置,需要和开始位置(setTimeout之后)的括号( 匹配。看了些文档后,写了下面的方法:

function match(str, startStr, item) {    var counter = 0,        end = -1,        matchLeft = item.charAt(0),        matchRight = item.charAt(1),        start = str.indexOf(startStr) + startStr.length;    search(start + 1);    function search(position) {        end = str.indexOf(matchRight, position);        if (end != -1) {            counter++;            var subStr = str.substring(start + 1, end).match(eval("/\\" + matchLeft + "/g"));            if (subStr !== null) {                var numsOfMatchLeft = subStr.length;            } else if (subStr === null) {                return;            }            if (counter > numsOfMatchLeft) {                return;            } else {                arguments.callee(end + 1);            }        } else {            console.warn('输入的配对符号有误');        }    }    return [start, end];}

参数

match函数接收3个参数,str是要匹配的文本,startStr是需匹配字符,在文本中的具体位置,为了保证唯一性,一般要带入字符左侧若干文本,item是要匹配的符号,按左右顺序写全两个,如'()','{}'等。匹配最上面的setTimeout那个例子,可以这样调用。

var text = 'setTimeout(function() {\        output.innerText += \'第三个异步函数,延迟1秒执行\n\';\    }, 1000);' match(text,'setTimeout(','()');//返回符号的开始,结束位置数组//[11, 71]

实现思路

左右匹配,只要把中间所有的匹配项找到即可。

()为例,首先从欲匹配符号(位置的右侧开始寻找),设定一个累加计数器,用来记录)的数量,如果找到,记下)的位置,计数器自增。

并且在(的位置与)的位置间,查找(的数量,与计数器进行比较。如果计数器的值小于(的数量,说明该)不是最终的与最开头的(相匹配的括号。如果计数器的值等于(的数量,说明所有()已经一一对应,下一个)就是最终的匹配括号。

重复上面的步骤,最终得到括号的位置。

这种方法不局限于括号,理论上可义匹配不相同的任意两项,也不局限于长度为1的字符,对位置稍加修改即可。

0 0