假设你有一个包含多个方法的C#类。其中一些方法调用了一个函数DoWorkAsync
。我需要一个正则表达式来找到函数的名称,并且只找到调用DoWorkAsync的函数。幸运的是,所有函数都有相同的签名:public object %name%(List<object> params)
,并且都以return null;
安全措施结束。
举例来说:
...
public object AddData(List<object> params) {
DoSomething();
DoSomething();
DoSomething();
return null;
}
public object ProcessData(List<object> params) {
DoSomething();
DoWorkAsync(); //this is an invocation
DoSomething();
return null;
}
public object RemoveData(List<object> params) {
DoSomething();
DoSomething();
DoSomething();
return null;
}
...
字符串
我首先尝试了这个简单的正则表达式(我使用SingleLine Option,所以“.”匹配新行):@"public object (?'funcname'.+?)\(List<object> params\).+?DoWorkAsync\(\);"
个
这样做的问题是第一个函数总是匹配,funcname
将是AddData
而不是ProcessData
,因为它最终会在打开函数后找到对DoWorkAsync
的调用。它不知道函数结束了,新的函数开始了。好的,所以我读了关于平衡正则表达式的文章,它应该处理这种事情。然后我尝试了这样的东西:@"(?:public object (?'funcname'.+?)\(List<object> params\)(?'count')|.+?DoWorkAsync\(\);.+?|return null;(?'-count'))*(?(count)(?!))"
个
这不起作用,因为它将匹配两个打开的函数和两个关闭的“return null”。我需要它在没有首先找到函数调用的情况下找到return时失败。我尝试了其他排列,例如:@"public object (?'funcname'.+?)\(List<object> params\).+?(?:public object .+?\(List<object> params\)(?!)|DoWorkAsync\(\);.+?).+?return null;"
个
但是没有任何效果。我认为平衡正则表达式可能是答案,如果我只能过滤最深的一层。或者,如果平衡不起作用,那么某种前瞻,这样在找到打开函数之后,如果你前瞻并在函数调用之前找到另一个打开函数,它就会失败。
有人知道吗?谢谢。
1条答案
按热度按时间uxhixvfz1#
我能够弄清楚它。我不得不做嵌套正则表达式。下面是我做的:
1.查找所有带有此正则表达式的函数:
@"public object (?'name'\S+)\(List<object> params\){(?'function'(?:[^{}]*|{(?'depth')|}(?'-depth'))*(?(depth)(?!)))}"
1.用我想替换的目标函数初始化一个队列:
var queue = new Queue<string>(); queue.Enqueue("DoWorkAsync");
1.使用while循环遍历队列:
字符串
1.在while内部,执行for循环,将调用该函数的任何函数添加到队列中:
型
1.在foreach循环之后,但仍然在while循环中,我只是替换了调用和定义:
型
就是这样!
我发现的一个警告是,如果任何函数是递归的,它将把自己添加到队列中并无限循环。这可以通过一组已经转换的函数并在foreach中过滤掉来解决。