使用c#从JavaScript文件中获取函数名和函数体代码
Fetching function name and body code from JavaScript file using C#
我需要从javascript文件中获取特定的函数和它的主体作为文本,并使用c#打印该函数作为输出。我需要给函数名和js文件作为输入参数。我尝试使用正则表达式,但不能达到预期的结果。以下是正则表达式的代码:
public void getFunction(string jstext, string functionname)
{
Regex regex = new Regex(@"function's+" + functionname + @"'s*'(.*')'s*'{");
Match match = regex.Match(jstext);
}
还有别的办法吗?
这个答案是基于你在注释中提供的假设,即c#函数只需要查找函数声明,而不需要任何形式的函数表达式。
正如我在注释中指出的那样,javascript太复杂了,无法用正则表达式有效地表达。要知道已经到达函数的末尾,唯一的方法是当括号全部匹配时,并且在这种情况下,您仍然需要考虑转义字符、注释和字符串。
我能想到的实现这一点的唯一方法是,从函数体的开始,直到括号匹配为止,实际上遍历每个字符,并跟踪出现的任何奇怪的东西。
这样的解决方案永远不会很漂亮。我已经拼凑了一个例子来说明它是如何工作的,但是知道javascript是如何充满小怪癖和陷阱的,我相信这里有许多没有考虑到的极端情况。我也确信它可以做得更整洁一些。
从我的第一个实验,下面应该处理转义字符,多行和单行注释,由",'或'分隔的字符串,以及正则表达式(即由/分隔)。
这应该会让你走得很远,尽管我很想看看人们在注释中能想出什么异常:
private static string GetFunction(string jstext, string functionname) {
var start = Regex.Match(jstext, @"function's+" + functionname + @"'s*'([^)]*')'s*{");
if(!start.Success) {
throw new Exception("Function not found: " + functionname);
}
StringBuilder sb = new StringBuilder(start.Value);
jstext = jstext.Substring(start.Index + start.Value.Length);
var brackets = 1;
var i = 0;
var delimiters = "`/''"";
string currentDelimiter = null;
var isEscape = false;
var isComment = false;
var isMultilineComment = false;
while(brackets > 0 && i < jstext.Length) {
var c = jstext[i].ToString();
var wasEscape = isEscape;
if(isComment || !isEscape)
{
if(c == @"'") {
// Found escape symbol.
isEscape = true;
} else if(i > 0 && !isComment && (c == "*" || c == "/") && jstext[i-1] == '/') {
// Found start of a comment block
isComment = true;
isMultilineComment = c == "*";
} else if(c == "'n" && isComment && !isMultilineComment) {
// Found termination of singline line comment
isComment = false;
} else if(isMultilineComment && c == "/" && jstext[i-1] == '*') {
// Found termination of multiline comment
isComment = false;
isMultilineComment = false;
} else if(delimiters.Contains(c)) {
// Found a string or regex delimiter
currentDelimiter = (currentDelimiter == c) ? null : currentDelimiter ?? c;
}
// The current symbol doesn't appear to be commented out, escaped or in a string
// If it is a bracket, we should treat it as one
if(currentDelimiter == null && !isComment) {
if(c == "{") {
brackets++;
}
if(c == "}") {
brackets--;
}
}
}
sb.Append(c);
i++;
if(wasEscape) isEscape = false;
}
return sb.ToString();
}
演示相关文章:
- 构造函数函数闭包变量
- 构造函数函数中的自执行函数的OO上下文/范围
- 为什么在构造函数函数中使用此关键字
- 正在将构造函数函数迁移到TypeScript
- 获取构造函数函数的最佳方式是在JavaScript中使用带名称空间的字符串表示
- Javascript函数对象体
- 为什么可以't我使用'var'在构造函数函数中
- 获取自定义对象构造函数函数名
- 在构造函数函数中创建只读(get)属性
- 正在检查类型构造函数函数
- Javascript中的内置构造函数函数
- 如何在JavaScript中的函数(函数本身就是一个参数)中传递参数
- 构造函数函数原型可枚举
- 为什么要设置原型's构造函数转换为其构造函数函数
- 从另一个javascript程序调用函数-函数式编程
- 构造函数函数.可以't覆盖对全局变量的引用
- 我得到一个函数a和函数C.函数B在函数中
- 使用构造函数函数的Javascript继承
- 将数组传递给函数-函数内部的数组为空
- 这种自调用匿名函数变体背后的原因