2017-01-13 15 views
0

Iは実際に私ができるタイプの文字列 "合計(SUM(_))" _などの一つまたは多くの(カンマで区切られた)関数呼び出し、引用符の間の文字列、ネストされたファンクション文字列はどのように一致させることができますか?

//should return true 
/sum\(sum\(_\)\)/.test('sum(sum(2,3,4))') 
/sum\(sum\(_\)\)/.test('sum(sum(a,b,c))') 
/sum\(sum\(_\)\)/.test('sum(sum(neg(2),neg(neg(3))))') 

ことができる たを有します文字列と他のパラメータとは一致しますが、ネストされた関数呼び出しと一致させようとすると複雑になります。

誰かがこのタイプの問題に対処するために作られたjavascriptの正規表現またはいくつかのライブラリでこれを行う方法を知っていますか?前もって感謝します。

+1

:あなたの再帰式を解析する方法についてのヒントを与えるための唯一の最初のドラフトです。再帰機能をサポートするregexエンジンでのみ可能です。 –

+0

クイックパーサーを書くだけで簡単だと思われます。 –

+0

@squint大丈夫ですが、コンテンツを解析しようとすると、かっこが常に途中にあります。どのようなヒントは、私はこのような何かを持っているとき、例えば "div(sum(sum(2,3)、3))"と評価されます。 – shuji

答えて

1

以下のようなパーサーを使用して内側の文字列を取得することをお勧めします。

var nestedFunctions = getInnerString("sum(sum(neg(2),neg(neg(3))))", 8) 
console.log(nestedFunctions); // should return -> neg(2),neg(neg(3)) 


function getInnerString(text, startIndex) { 
    startIndex = !startIndex ? 0 : startIndex; 
    var endIndex = getEndIndexForParathesis(text, startIndex); 
    var innerString = text.substring(startIndex, endIndex); 
    return innerString; 
} 

function getEndIndexForParathesis(text, start) { 
    start = !start ? 0 : start; 
    var subGroups = 0 
    var endIndex = 0; 
    for (var i = start, len = text.length; i < len; i++) { 
    var letter = text[i] 
    if (letter === '(') { 
     subGroups++; 
     continue; 
    } 
    if (letter === ')' && subGroups != 0) { 
     subGroups--; 
     continue; 
    } 
    if (letter === ')' && subGroups == 0) { 
     endIndex = i; 
     break; 
    } 
    } 
    return endIndex; 
} 

これはうまくいきたいと思います。私は正規表現を試しましたが、3つのケースすべてで内部のテキストを抽出することは非常に困難になりました。

+0

良い@Piyushありがとうたくさん – shuji

+0

@ shuji問題ありません! – Piyush

0

以下は、解析アルゴリズムの例です。関数呼び出しでコンマを使用しない場合は、最も効果的です。コンマは現時点でトップレベルでしか働いていません。コンマを使用する場合は、アルゴリズムをさらに改善する必要があります。あなたは、単一の正規表現でそれを行うことはできません

var expression = "neg(2),neg(neg(3))"; 
 
var data = []; 
 
parse(data, expression); 
 
console.log(data); 
 

 
function parse(data, expression) { 
 
    var expressionArray = expression.split(","); 
 
    for(var i = 0; i < expressionArray.length; i++) { 
 
    var element = expressionArray[i]; 
 
    var match = element.match(/^([a-zA-Z]+?)\((.*)\)$/); 
 
    var entry = {}; 
 
    data.push(entry); 
 
    
 
    entry.element = element; 
 
    entry.children = []; 
 
    if(match) { 
 
     entry.function = match[1]; 
 
     parse(entry.children, match[2]); 
 
    } 
 
    } 
 
}

関連する問題