2017-01-13 5 views
0

У меня есть строка типа «сумма (сумма (_))» , в которых _ может быть один или несколько (через запятую) вызов функции, строка в кавычках и т.д.Как я могу сопоставить вложенную строку функции?

//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

Вы не можете сделать это с помощью одного регулярного выражения. Это возможно только при использовании двигателей регулярных выражений, которые поддерживают функцию рекурсии. –

+0

Кажется, было бы достаточно просто написать быстрый парсер. –

+0

@squint ok достаточно справедливо, но когда я пытаюсь разобрать содержимое, круглые скобки всегда в пути. Любой намек будет оценен, например, когда у меня есть что-то вроде этого: «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; 
} 

Я надеюсь, что это сработает для вас. Я попробовал regex, но было очень сложно извлечь внутренний текст во всех трех случаях.

+0

nice @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]); 
 
    } 
 
    } 
 
}