返回方法调用字符串中的顶级参数的计数

时间:2017-03-22 07:10:11

标签: javascript parsing typescript

假设我有一个字符串,它包含一些c-ish语言的方法调用:

var codeLine = 'method1(var1, var2, method2(var3, method3(var4, var5)),var6);';

计算传递给顶级函数(method1)的参数数量的最简单方法是什么?

在上面的例子中,我将寻找4的结果。

如果方法不完整(想象它正在输入),我还需要这个解决方案才能正常运行:

method1(var1, var2, method2(var3, meth

将返回3.

我理解“正确”的方法是使用像antlr这样的工具解析语言,但我希望有一个快速简便的解决方法。

如果您好奇,这是针对提供签名帮助支持的vscode扩展程序

更新

捅了一下......

function findTopLevelParamCount(s){
    //trim top level function away
    s = s.substr(s.indexOf('(')+1,s.lastIndexOf(')')-s.indexOf('(')-1);
    console.log(s);
    while(s.indexOf('(') >= 0){
       s = s.substr(0,s.indexOf('(')) + (s.indexOf(')')==-1?'':s.substr(s.lastIndexOf(')')+1));
       console.log(s);
    }
    return s.split(',').length;
}

var code = 'method1(var1, var2, method2(var3, method3(var4, var5)), var6);';
console.log(findTopLevelParamCount(code));

如果签名不完整,则无效。同样打破像method1(var1, (var1-va2))这样的parethsis分组。

1 个答案:

答案 0 :(得分:2)

/**
 * parse param count from string by specific level
 * @param  String str     string to be parsed
 * @param  Number level   function call level, default as 1(top)
 * @return Number         param count
 */
function parseParamCount(str, level){
  level = level || 1;
  var ary = str.split(',');
  var tokenLevel = 0;
  var count = 0;
  for(var i = 0, l = ary.length; i < l; i ++){
    var token = ary[i];
    // calc ')' length in token, then increase level by that
    var startBracketMatch = token.match(/\(/g);
    if(startBracketMatch){
      if(tokenLevel <= level)count++;
      tokenLevel += startBracketMatch.length;
    }else{
      if(tokenLevel === level)count ++;
    } 
    
    // calc ')' length in token, then decrease level by that
    var endBracketMatch = token.match(/\)/g);
    if(endBracketMatch){
      tokenLevel -= endBracketMatch.length;
    }
  }
  return count;
}

var test1 = 'method1(var1, var2, method2(var3, method3(var4, var5)),var6);';
var test2 = 'method1(var1, var2, method2(var3, meth';
var test3 = 'method1(method2(name), aaa)';

console.log(parseParamCount(test1));
console.log(parseParamCount(test2));
console.log(parseParamCount(test3));

试一试

针对test3进行了更新。