Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
查找JavaScript表达式的部分_Javascript_Regex_Expression_Conditional Statements - Fatal编程技术网

查找JavaScript表达式的部分

查找JavaScript表达式的部分,javascript,regex,expression,conditional-statements,Javascript,Regex,Expression,Conditional Statements,假设我有一个JavaScript表达式作为字符串,如下所示: string = ' collections.users[ currentUsers[ ids[1].id ] ] && users[ ids[1].id ]' 现在我需要得到这个表达式的一些部分,它们是我所做工作的“依赖项” 这就是我需要从字符串中提取的内容 result = [ 'collections.users[ currentUsers[ ids[1].id ] ]',

假设我有一个JavaScript表达式作为字符串,如下所示:

string = ' collections.users[ currentUsers[ ids[1].id ] ] && users[ ids[1].id ]'
现在我需要得到这个表达式的一些部分,它们是我所做工作的“依赖项”

这就是我需要从字符串中提取的内容

result = [
         'collections.users[ currentUsers[ ids[1].id ] ]', 
          'currentUsers[ ids[1].id]', 'ids[1].id',
          'users[ ids[1].id ]', 'ids[1].id'
         ]
它基本上需要每个包含
[*]
的“变量”

这是每一个可能导致表达式改变的变量,我已经尝试了大约3天了,到目前为止,我尝试了但失败了

  • 使用正则表达式查找所有依赖项(失败)

  • 我曾尝试使用“如果括号打开,请执行某些操作”等条件拆分字符串,但失败了

    这真的很难理解,我在代码中没有任何尝试过的东西,因为我刚刚删除并重新开始

  • 我知道这可能有点“本地化”,但我已经在JavaScript聊天上问了几天的建议,但没有得到任何结果,我没有其他选择

    有人对如何实现这一点有什么建议吗?记住这个字符串不是静态的,可能有更深的条件

    有人为此建议使用JSON,但我不知道这是怎么回事,你怎么看


    由于问题的性质,我将给50+赏金提供最佳答案/建议

    您可能需要使用递归函数并迭代每个字符。每次你点击一个开放的括号,你就会进入一个新的递归层;每次你击中一个较近的支架,你就退出一个

    我相信这正是你想要的

    var toParse = 'collections.users[ currentUsers[ ids[1].id ] ] && users[ ids[1].id ]';
    var operators = ['&','|','+','-','=','/','*'];
    var answer = [];
    
    parseBrackets(0);
    
    function parseBrackets(start) {
        var openBrackets = 0;
        var currentString = '';
        for (var i = start; i < toParse.length; i++) {
            if (toParse[i] == '[') {  // open bracket
                if (openBrackets == 0) {
                    parseBrackets(i + 1);
                }
                currentString += toParse[i];
                openBrackets++;
            } else if (toParse[i] == ']' && openBrackets-- == 0) { // close bracket
                answer.push(currentString);
                return;
            } else if (operators.indexOf(toParse[i]) >= 0) { // this is an expression operator, don't include it
                if (currentString != '') {
                    answer.push(currentString);
                }
                currentString = '';
            } else { // add this character to the current string
                currentString += toParse[i];
            }
        }
        answer.push(currentString); // add the current string to the list of parsed 'dependencies'
    }
    
    console.log(answer);
    

    Regexp不适合这个问题,因为Regexp不能“计数”。也就是说,无论您的regexp有多复杂,都会有一些不被接受的括号嵌套级别

    您真正需要的是一个解析器。有些解析器生成器使用语法规则生成代码。这里有一些:

    你的规则看起来很简单。大概是这样的:

    Expression = AnythingExceptBrackets '[' Expression ']' AnythingExceptBrackets 
                 | AnythingExceptBrackets 
    
    AnythingExceptBrackets = [^\\[\\]]+ 
    

    当您获得生成器时,剩下的唯一一步就是将已识别的标记粘贴到结果数组中。

    为了成功解析短语,必须知道短语的完整结构。不可能从给出的一个例子中确定所有可能的结构。然而,在做出一些假设后,我使用扩展的Backus–Naur表单(EBNF)定义了一个可能的结构

    假设每个数组元素可以有一个整数、一个变量或另一个数组元素作为索引,变量和数组元素可以有使用点表示法编写的属性。数组元素列表之间可以有运算符

    然后,您可以根据需要修改和扩展此结构

    扩展巴科斯-诺尔形式表示法

    {}0或更多

    []1个或更多

    ()组

    letter=“a”|“b”|“c…”“x”|“y”|“z”|“a”|“b”|“…”|“y”|“z”

    数字=0“|”1“|”2“|”3“|”4“|”5“|”6“|”7“|”8“|”9

    整数=[位数]

    术语=[字符|位]

    标识符=($| |字符){term}

    属性=.char{term}

    变量=标识符{property}

    索引=数字|变量|数字

    数组=变量“[”索引“]”{property}

    运算符=“&&&”|“|”|+“|”-“|”*“|”/”

    短语=数组{运算符数组}:

    有一个解析短语并生成给定示例结果的

    代码是

    letter = /[a-zA-Z]/;
    digit = /[0-9]/;
    join = /[&|+\-*]/;  //possible operators
    
    
    var phrase=' collections.users[ currentUsers[ ids[1].id ] ] && users[ ids[1].id ]';
    var ptr=0;
    var stack=[];
    
    phrase=phrase.replace(/\s/g,''); //remove extraneous white space
    phrase+=':'; //add : as terminator
    
    var crctr=readNext();
    
    getArray();         
    document.getElementById('results').innerHTML=setResults();
    
    function getArray() {
        var L=new List();
        L.name=getVariable();
        L.index=getIndex();
        crctr=readNext();
        if(crctr=='.') {
            crctr=readNext();
            L.property=getProperty();
        }   
        stack.push(L);
        if(crctr !=':') { //not end of phrase
            if (join.test(crctr)) {     
                readJoin();         
                getArray();
            }
        }
    }
    
    function getIndex() {
        var indx='';
        if(crctr=="[") {
            crctr=readNext();   
            if(digit.test(crctr))
            {
                indx=getInteger();
                if(crctr==']') {
                    return indx;
                }
            }
            else {
                indx=getVariable(); 
                if(crctr=="]"){
                    return indx;
                }
                else if(crctr=="[") {                   
                    var L=new List();
                    L.name=indx;
                    L.index=getIndex();
                    crctr=readNext();
                    if(crctr=='.') {
                        crctr=readNext();
                        L.property=getProperty();
                    }
                    stack.push(L);          
                    return L;
                }
            }
        }
        else {
            throw 'index error';
        }
    }
    
    
    
    function getVariable() {
        var v="";   
        if(crctr=="$" || crctr=="_" || letter.test(crctr)) {
            v+=crctr;
            crctr=readNext();
            v+=getIdentifier();
            if (crctr==".") {
                v+=crctr;
                crctr=readNext();
                v+=getProperty();
            }
            return v;   
        }
        else {
            throw 'variable error';
        }
    }
    
    function getIdentifier() {
        var id="";
        if(crctr=="$" || crctr=="_" || letter.test(crctr)) {
            id=crctr;
            crctr=readNext();
            id+=getTerm();
            return id;  
        }
        else {
            throw 'Identifier error';
        }
    }
    
    function getTerm() {
        var t="";
        while(letter.test(crctr) || digit.test(crctr)) {
            t+=crctr;
            crctr=readNext();
        }
        return t;
    }
    
    function getProperty() {
        var p='';
        if(letter.test(crctr)) {
            p=crctr;
            crctr=readNext();
            while(letter.test(crctr) || digit.test(crctr)) {
                p+=crctr;
                crctr=readNext();
            }
            if(crctr=='.') {
                p+=crctr;
                crctr=readNext();
                p+=getProperty();
            }
            else {
                return p;
            }
        }
        else {
            throw 'property error';
        }
    }
    
    function getInteger() {
        var i='';
        while(digit.test(crctr)) {
            i+=crctr;
            crctr=readNext();
        }
        return i;
    }
    
    function readJoin() {
        if(crctr=="&" || crctr=="|") {
            crctr=readNext();
        }
        crctr=readNext();
    }
    
    function readNext(){
        var crctr=phrase.charAt(ptr);
        ptr+=1;
        return crctr;
    }
    
    function List() {
        this.name='';
        this.index='';
        this.property='';
    }
    
    function setResults() {
        var r='results = [';
        while(stack.length>1) {
            var A=stack.pop();
            r+='<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'+listArrays(A)+',';
        }
        var A=stack.pop();
        r+='<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'+listArrays(A);
        return r+='<br>]';
    }
    
    function listArrays(A) {        
        if(A.index.name) { //A.index is array   
            var name=A.name;
            var indx=A.index;
            var prp='';
            if(A.property !='') {
                prp='.'+A.property;
            }
            return A.name+'['+listArrays(A.index)+']'+prp;
        }
        else {
            var name=A.name;
            var indx=A.index;
            var prp='';
            if(A.property !='') {
                prp='.'+A.property;
            }
            return A.name+'['+A.index+']'+prp;
        }
    }
    
    字母=/[a-zA-Z]/; 数字=/[0-9]/; join=/[&+\-*]/;//可能的运算符 变量短语='collections.users[currentUsers[ids[1].id]]和&users[ids[1].id]'; var-ptr=0; var堆栈=[]; 短语=短语。替换(//\s/g',);//删除多余的空白 短语+=':';//添加:作为终止符 var crctr=readNext(); getArray(); document.getElementById('results')。innerHTML=setResults(); 函数getArray(){ var L=新列表(); L.name=getVariable(); L.index=getIndex(); crctr=readNext(); 如果(crctr=='。){ crctr=readNext(); L.property=getProperty(); } 堆栈推送(L); 如果(crctr!=':'){//不是短语的结尾 if(join.test(crctr)){ readJoin(); getArray(); } } } 函数getIndex(){ var indx=''; 如果(crctr==“[”){ crctr=readNext(); if(数字测试(crctr)) { indx=getInteger(); 如果(crctr==']'){ 返回indx; } } 否则{ indx=getVariable(); 如果(crctr==“]”){ 返回indx; } 如果(crctr==“[”){ var L=新列表(); L.name=indx; L.index=getIndex(); crctr=readNext(); 如果(crctr=='。){ crctr=readNext(); L.property=getProperty(); } 堆栈推送(L); 返回L; } } } 否则{ 抛出“索引错误”; } } 函数getVariable(){ var v=“”; 如果(crctr==“$”|| crctr==“|”字母测试(crctr)){ v+=crctr; crctr=readNext(); v+=getIdentifier(); 如果(crctr==”){ v+=crctr; crctr=readNext(); v+=getProperty(); } 返回v; } 否则{ 抛出“变量错误”; } } 函数getIdentifier(){ var id=“”; 如果(crctr==“$”|| crctr==“|”字母测试(crctr)){ id=crctr; crctr=readNext(); id+=getTerm(); 返回id; } 否则{ 抛出“标识符错误”; } } 函数getTerm(){ var t=“”; while(字母测试(crctr)| |数字测试(crctr)){ t+=crctr; crctr=readNext(); } 返回t; } 函数getProperty(){ var p=''; if(字母测试(crctr)){ p=crctr; crctr=readNext(); while(字母测试(crctr)| |数字测试(crctr)){ p+=crctr; crctr=readNext(); }
    letter = /[a-zA-Z]/;
    digit = /[0-9]/;
    join = /[&|+\-*]/;  //possible operators
    
    
    var phrase=' collections.users[ currentUsers[ ids[1].id ] ] && users[ ids[1].id ]';
    var ptr=0;
    var stack=[];
    
    phrase=phrase.replace(/\s/g,''); //remove extraneous white space
    phrase+=':'; //add : as terminator
    
    var crctr=readNext();
    
    getArray();         
    document.getElementById('results').innerHTML=setResults();
    
    function getArray() {
        var L=new List();
        L.name=getVariable();
        L.index=getIndex();
        crctr=readNext();
        if(crctr=='.') {
            crctr=readNext();
            L.property=getProperty();
        }   
        stack.push(L);
        if(crctr !=':') { //not end of phrase
            if (join.test(crctr)) {     
                readJoin();         
                getArray();
            }
        }
    }
    
    function getIndex() {
        var indx='';
        if(crctr=="[") {
            crctr=readNext();   
            if(digit.test(crctr))
            {
                indx=getInteger();
                if(crctr==']') {
                    return indx;
                }
            }
            else {
                indx=getVariable(); 
                if(crctr=="]"){
                    return indx;
                }
                else if(crctr=="[") {                   
                    var L=new List();
                    L.name=indx;
                    L.index=getIndex();
                    crctr=readNext();
                    if(crctr=='.') {
                        crctr=readNext();
                        L.property=getProperty();
                    }
                    stack.push(L);          
                    return L;
                }
            }
        }
        else {
            throw 'index error';
        }
    }
    
    
    
    function getVariable() {
        var v="";   
        if(crctr=="$" || crctr=="_" || letter.test(crctr)) {
            v+=crctr;
            crctr=readNext();
            v+=getIdentifier();
            if (crctr==".") {
                v+=crctr;
                crctr=readNext();
                v+=getProperty();
            }
            return v;   
        }
        else {
            throw 'variable error';
        }
    }
    
    function getIdentifier() {
        var id="";
        if(crctr=="$" || crctr=="_" || letter.test(crctr)) {
            id=crctr;
            crctr=readNext();
            id+=getTerm();
            return id;  
        }
        else {
            throw 'Identifier error';
        }
    }
    
    function getTerm() {
        var t="";
        while(letter.test(crctr) || digit.test(crctr)) {
            t+=crctr;
            crctr=readNext();
        }
        return t;
    }
    
    function getProperty() {
        var p='';
        if(letter.test(crctr)) {
            p=crctr;
            crctr=readNext();
            while(letter.test(crctr) || digit.test(crctr)) {
                p+=crctr;
                crctr=readNext();
            }
            if(crctr=='.') {
                p+=crctr;
                crctr=readNext();
                p+=getProperty();
            }
            else {
                return p;
            }
        }
        else {
            throw 'property error';
        }
    }
    
    function getInteger() {
        var i='';
        while(digit.test(crctr)) {
            i+=crctr;
            crctr=readNext();
        }
        return i;
    }
    
    function readJoin() {
        if(crctr=="&" || crctr=="|") {
            crctr=readNext();
        }
        crctr=readNext();
    }
    
    function readNext(){
        var crctr=phrase.charAt(ptr);
        ptr+=1;
        return crctr;
    }
    
    function List() {
        this.name='';
        this.index='';
        this.property='';
    }
    
    function setResults() {
        var r='results = [';
        while(stack.length>1) {
            var A=stack.pop();
            r+='<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'+listArrays(A)+',';
        }
        var A=stack.pop();
        r+='<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'+listArrays(A);
        return r+='<br>]';
    }
    
    function listArrays(A) {        
        if(A.index.name) { //A.index is array   
            var name=A.name;
            var indx=A.index;
            var prp='';
            if(A.property !='') {
                prp='.'+A.property;
            }
            return A.name+'['+listArrays(A.index)+']'+prp;
        }
        else {
            var name=A.name;
            var indx=A.index;
            var prp='';
            if(A.property !='') {
                prp='.'+A.property;
            }
            return A.name+'['+A.index+']'+prp;
        }
    }