从类文件中提取函数

时间:2017-09-17 17:46:08

标签: javascript regex actionscript-3 recursion

我正在使用正则表达式从Javascript中提取AS3类文件中的函数。 但是我的函数有一个内部括号的问题(如内部if或者其他)。

我看到我可以使用<div class="wrapper"> <div class="item" style="width: 100px; height: 150px; left:10px"> <div class="item-content"> <!-- Safe zone, enter your custom markup --> This can be anything1. <!-- Safe zone ends --> </div> </div> <div class="item" style="width: 100px; height: 100px; left:120px"> <div class="item-content"> <!-- Safe zone, enter your custom markup --> This can be anythin2. <!-- Safe zone ends --> </div> </div> <div class="item" style="width: 200px; height: 200px; left:10px; top: 160px"> <div class="item-content"> <!-- Safe zone, enter your custom markup --> This can be anything3. <!-- Safe zone ends --> </div> </div> </div> 递归执行此操作,但这不适用于Javascript,因为不支持递归img { max-width: 50vw; width: 50%; }

我想知道是否有人可以帮助我找到另一种解决方案。 这是我的regex101 test = https://regex101.com/r/eE6mX3/1

[HttpPost]
public ActionResult Details(Guid? personID)
{
    if(personID != null)
    {
        //do some work
    }

}

感谢所有能帮助我的人。

2 个答案:

答案 0 :(得分:0)

警告!你继续阅读,风险自负!真是丑陋的正则表达式!!!

(这是我最初开始的答案,它不应该被认真对待。但是它背后有很多工作,所以无论如何我都会发布它。我的另一个答案应该是你的答案想。)

现在......这在某种程度上是可能的 - 如果嵌套级别的数量有限,可以这样做。

(我应该提一下,我没有AS3的经验,并且无法将你在regex101上的例子与我用google搜索的内容联系起来。)

假设它是普通 JS函数的主体,你不能抓住这个解决方案应该(可以)为你做。

<强>嵌套

使用{[^{}]*}可以轻松匹配内部范围。这匹配两个周围的大括号和它们之间的任何内容([^{}]*是一个否定的字符类,匹配任何字符 {} - *表示任何次数)。实例:

&#13;
&#13;
var re = /{[^{}]*}/,
    str = 'one { two { three { four { five } six } seven } eight } nine';
    
    document.write(str.match( re ));
&#13;
&#13;
&#13;

现在,如果我们需要匹配嵌套级别,只需将级别添加到正则表达式{[^{}]*{[^{}]*}[^{}]*}即可轻松完成。实例:

&#13;
&#13;
var re = /{[^{}]*{[^{}]*}[^{}]*}/,
    str = 'one { two { three { four { five } six } seven } eight } nine';
    
    document.write(str.match( re ));
&#13;
&#13;
&#13;

即使是四个级别 - 没问题:{[^{}]*{[^{}]*{[^{}]*{[^{}]*}[^{}]*}[^{}]*}[^{}]*}。实例:

&#13;
&#13;
var re = /{[^{}]*{[^{}]*{[^{}]*{[^{}]*}[^{}]*}[^{}]*}[^{}]*}/,
    str = 'one { two { three { four { five } six } seven } eight } nine';
    
    document.write(str.match( re ));
&#13;
&#13;
&#13;

当然,你可以更进一步,但它开始(?)看起来很讨厌。

字符串和评论

现在你可能会问自己 - &#34;字符串和评论怎么样?&#34; (如Wiktor所述)。嗯,有一个解决方案。

如果我们使用字符串{one /* two } */ three ' { four }' "} five {" } // {six}(表示带有注释的JS代码行),我们可以轻松地将它们自己匹配单独的部分

  • '(?:\\'|[^'])*'匹配单引号字符串(允许转义单引号)。
  • "(?:\\"|[^"])*"匹配双引号字符串(允许转义双引号)。
  • \/\*(?:[^*]*)*?\*\/匹配/* abc */样式评论(可能是多行)。
  • \/\/.*匹配// abc(行尾)样式评论

将这些加入到交替中会匹配所有这些 - 如下所示:

&#13;
&#13;
var re = /'(?:\\'|[^'])*'|"(?:\\"|[^"])*"|\/\*(?:[^*]*)*?\*\/|\/\/.*/g,
    str = '{one /* two } */ three \'{ four }\' "} five {" } // {six}';
    
    document.write(str.match( re ).join('<br/>'));
&#13;
&#13;
&#13;

首先是评论/* two } */,然后是字符串' { four }'  和"} five {",最后是// {six}评论。

全部放在一起

首先匹配字符串/注释部分,我们可以避免在搜索匹配对时包含不需要的括号。我们还将在交替中包含一个由所有 legal Javascript字符(空格,字符,运算符,标点符号等)组成的字符类。

然后我们需要获得内部范围:

{(?:(?:'(?:\\'|[^'])*?'|"(?:\\"|[^"])*?"|\/\*(?:[^*]*)*?\*\/|\/\/.*)|[\s\w-+\/*.=,();|&[\]:])*}

实例:

&#13;
&#13;
var re = /{(?:(?:'(?:\\'|[^'])*?'|"(?:\\"|[^"])*?"|\/\*(?:[^*]*)*?\*\/|\/\/.*)|[\s\w-+\/*.=,();|&[\]:])*}/,
    code = '// Example code\nfunction(a,b,c) {\n\t// Return sum of all arguments\n\treturn a+b+c;\n\t// Ignore this: }\n}\n';
    
document.write('<span style="background-color:lightblue;">ORIGINAL CODE:<br/></span>');
document.write(code.replace(/\n/g, '<br/>'));

document.write('<span style="background-color:lightblue;">INNER SCOPE:<br/></span>');
document.write(code.match(re)[0].replace(/\n/g, '<br/>'));
&#13;
&#13;
&#13;

将此与上面解释的嵌套逻辑相结合,我们将拥有(一个真正复杂)正则表达式,这应该可以解决这个问题,具有前面提到的限制。 (必须进行多级嵌套可能会导致超时)。

(?:{(?:(?:'(?:\\'|[^'])*?'|"(?:\\"|[^"])*?"|\/\*(?:[^*]*)*?\*\/|\/\/.*)|[\s\w-+\/*.=,();|&[\]:])*(?:{(?:(?:'(?:\\'|[^'])*?'|"(?:\\"|[^"])*?"|\/\*(?:[^*]*)*?\*\/|\/\/.*)|[\s\w-+\/*.=,();|&[\]:])*(?:{(?:(?:'(?:\\'|[^'])*?'|"(?:\\"|[^"])*?"|\/\*(?:[^*]*)*?\*\/|\/\/.*)|[\s\w-+\/*.=,();|&[\]:])*(?:{(?:(?:'(?:\\'|[^'])*?'|"(?:\\"|[^"])*?"|\/\*(?:[^*]*)*?\*\/|\/\/.*)|[\s\w-+\/*.=,();|&[\]:])*(?:{(?:(?:'(?:\\'|[^'])*?'|"(?:\\"|[^"])*?"|\/\*([^*]*)*?\*\/|\/\/.*)|[\s\w-+\/*.=,();|&[\]:])*})?(?:(?:'(?:\\'|[^'])*?'|"(?:\\"|[^"])*?"|\/\*([^*]*)*?\*\/|\/\/.*)|[\s\w-+\/*.=,();|&[\]:])*})?(?:(?:'(?:\\'|[^'])*?'|"(?:\\"|[^"])*?"|\/\*([^*]*)*?\*\/|\/\/.*)|[\s\w-+\/*.=,();|&[\]:])*})?(?:(?:'(?:\\'|[^'])*?'|"(?:\\"|[^"])*?"|\/\*(?:[^*]*)*?\*\/|\/\/.*)|[\s\w-+\/*.=,();|&[\]:])*})?(?:(?:'(?:\\'|[^'])*?'|"(?:\\"|[^"])*?"|\/\*(?:[^*]*)*?\*\/|\/\/.*)|[\s\w-+\/*.=,();|&[\]:])*})?

OMG !!! 我创造了一个怪物!)

&#13;
&#13;
var re = /{(?:(?:'(?:\\'|[^'])*?'|"(?:\\"|[^"])*?"|\/\*(?:[^*]*)*?\*\/|\/\/.*)|[\s\w-+\/*.=,();|&[\]:])*(?:{(?:(?:'(?:\\'|[^'])*?'|"(?:\\"|[^"])*?"|\/\*(?:[^*]*)*?\*\/|\/\/.*)|[\s\w-+\/*.=,();|&[\]:])*(?:{(?:(?:'(?:\\'|[^'])*?'|"(?:\\"|[^"])*?"|\/\*(?:[^*]*)*?\*\/|\/\/.*)|[\s\w-+\/*.=,();|&[\]:])*(?:{(?:(?:'(?:\\'|[^'])*?'|"(?:\\"|[^"])*?"|\/\*(?:[^*]*)*?\*\/|\/\/.*)|[\s\w-+\/*.=,();|&[\]:])*(?:{(?:(?:'(?:\\'|[^'])*?'|"(?:\\"|[^"])*?"|\/\*(?:[^*]*)*?\*\/|\/\/.*)|[\s\w-+\/*.=,();|&[\]:])*})?(?:(?:'(?:\\'|[^'])*?'|"(?:\\"|[^"])*?"|\/\*(?:[^*]*)*?\*\/|\/\/.*)|[\s\w-+\/*.=,();|&[\]:])*})?(?:(?:'(?:\\'|[^'])*?'|"(?:\\"|[^"])*?"|\/\*(?:[^*]*)*?\*\/|\/\/.*)|[\s\w-+\/*.=,();|&[\]:])*})?(?:(?:'(?:\\'|[^'])*?'|"(?:\\"|[^"])*?"|\/\*(?:[^*]*)*?\*\/|\/\/.*)|[\s\w-+\/*.=,();|&[\]:])*})?(?:(?:'(?:\\'|[^'])*?'|"(?:\\"|[^"])*?"|\/\*(?:[^*]*)*?\*\/|\/\/.*)|[\s\w-+\/*.=,();|&[\]:])*}/g,
    unnecessary_complex_code = "var str='123';\n\nfunction /* 123 * 4 * / */ test(\n// qwe\nparam // qwe\n, rapam\n) // \n{\n\ndocument /* qwe*/ . // write\nwrite ( /*\ntest\n*/ test(123) // );\n);\n\n	if(param===rapam) {\n		if( false ) {\n			// Another nested level\n			var another_level = {\n				test: { result: true  }\n			};\n		}\n		return // 'FALSE';\n			'TRUE;\n	} else return /* 'TRUE';\n	*/ 'FALSE'\n;\n  /*\n}\n*/\n}\n";
    
    console.log('Code used:');
    console.log(unnecessary_complex_code);
    console.log('Result:');
    console.log(unnecessary_complex_code.match(re));
&#13;
&#13;
&#13;

答案 1 :(得分:0)

这可能比您想象的要容易,并且不需要任何正则表达式解析;)

在解释它之前,更容易展示一个例子:

// This is an example of how a function may look

function Demo(first, second, third) {
  // Concatenate the first and second if third is undefined
  if(!third) { // This is to illustrate that a { doesn't cause any problem
    return first + ' - ' + second;
  }
  if(third==='first') { /*
    No problem with } this either
    */ return first;
  }
  if(third==='second') {
    return second;
  }
  else {
    if(third==='first and second') {
      return first + ' and ' + second;
    }
  }
}

// Now show what the function returns when invoked
console.log('The function returns:\n' + Demo('one', 'two'));

// And now - the magic: show the function definition
console.log('The function definition is:\n' + Demo);
span.result {
  background-color: lightblue;
}
span.definition {
  background-color: wheat;
}

访问不带()的函数将返回函数定义,而不是函数的结果。