C#正则表达式搜索虚线函数及其参数

时间:2016-09-19 06:47:52

标签: c# .net regex vb.net

我需要在文本字符串中搜索所有出现类似链接C#的函数。例如,我想打破每个方法及其字符串的括号参数,例如:

object.method(1, "2", abc).method2().method3("test(), 1, 2, 3").method4("\"Hi\"")

这是我几乎工作的正则表达式模式:

(?<objectName>[^\}]*?)\.(?<methodName>[^\}]*?)\(((?:[^;"']|"[^"]*"|'[^']*')+)*?\)

这正确地提取了objectName和第一个methodName,但是

  

1,“2”,abc).method2()。method3(“test,1,2,3”)。method4(“\”Hi \“”

将第三个参数全部改为“$ 1”。

我最近的方法是通过删除objectName规范来划分和征服,因为这很容易解析。这导致我使用:

\.(?<methodName>[^(]*?)\(((?:[^;"']|"[^"]*"|'[^']*')+)*?\)

在没有objectName的情况下,产生与之前类似的结果。我这样做是为了看看我是否可以获得全局结果,但可以获得正确的正则表达式语法。

总之,我需要将多个链式.method(参数)出现解析为名为“methodName”和“parameters”的组成部分。我推断了一些事情,但我的正则表达技巧充其量是生锈的,目前我无法克服这个问题。我感谢您提供的任何帮助。

我一直在使用此网站进行测试:http://regexstorm.net/tester

更新:为了澄清,要求不包括支持C#lambda表达式,只包括虚线函数语法。这不是一个完整的C#解析器。唯一需要的是点缀方法链接。我为任何困惑道歉。我期待突破的模式是:

object.method(arguments).method(arguments).method(arguments)...

我的方法是首先提取对象名称,这是一个不需要使用正则表达式的简单操作。现在,这将使正则表达式解析成以下两个组成部分:

.method(arguments).method(arguments).method(arguments)...

哪会产生:

method   arguments
method   arguments
method   arguments
...

参数可能为null(缺失),如.method(),或者方法实际上可能是属性(没有括号和参数),如:

.method.method().method(arguments)

哪会产生:

method   (null)
method   (string.Empty)
method   arguments

参数将包含开括号和右括号之间的所有内容;这些不需要在此时解析,因为这些将在后续的Regex操作中处理。

在我看来,在Regex的能力范围内,可以检测这种简单的dot-method-openPar-argumentsStr-closePar,dot-method-openPar-argumentsStr-closePar等等。

这是语法的范围 - 没有评论,没有lambda - 只是object.method(arguments).method()......

我希望这会有所帮助。

1 个答案:

答案 0 :(得分:1)

这不能通过正则表达式正确完成,因为你的参数太不可预测了,正则表达式语法级别与C#解析器语法无法比较。例如,它可以包含任何内容的字符串:

method1("x.hiThere().lol()").method2()

它可以嵌套:

method1(x=>method2().method3())

它可以这样做:

a("b().c()",d=> d(").hi()"))

对于您的问题解决方案,您需要了解Grammars,并为此特定任务编写C#语法。在框架方面,您可以从ANTLR项目开始。

<强>解释

因为你不能这样做的原因是语法类型的差异。 正则表达式使用常规语言,并且在Chomsky层次结构中是 Type-3 。 C#使用无上下文语言,在Chomsky层次结构中是 Type-2

如果你直观地表示它,C#是比正则表达式语言更强大的语言:

enter image description here

例如,您的案例属于解析器的坑仅仅是因为C#中的lambda:

method1(x=>
{
    ....
    /* some code here */
    ....
}).method2()