使用正则表达式解析签名,使用数组返回值“有趣”

时间:2014-12-15 05:20:07

标签: c# regex parsing signature

我有这个[讨厌的]正则表达式来捕获包含桶中所有部分的VBA过程签名:

    public static string ProcedureSyntax
    {
        get
        {
            return
                @"(?:(?<accessibility>Friend|Private|Public)\s)?(?:(?<kind>Sub|Function|Property\s(Get|Let|Set)))\s(?<identifier>(?:[a-zA-Z][a-zA-Z0-9_]*)|(?:\[[a-zA-Z0-9_]*\]))\((?<parameters>.*)?\)(?:\sAs\s(?<reference>(((?<library>[a-zA-Z][a-zA-Z0-9_]*))\.)?(?<identifier>([a-zA-Z][a-zA-Z0-9_]*)|\[[a-zA-Z0-9_]*\]))(?<array>\((?<size>(([0-9]+)\,?\s?)*|([0-9]+\sTo\s[0-9]+\,?\s?)+)\))?)?";
        }
    }

部分内容是过度杀戮,并且会匹配非法数组语法(在程序签名的上下文中),但这不是我现在关注的问题。

问题在于这一部分:

\((?<parameters>.*)?\)
当函数(或属性getter)返回一个数组时,

会中断,因为签名看起来像这样:

Public Function GetSomeArray() As Variant()

或者像这样:

Public Function GetSomeArray(ByVal foo As Integer) As Variant()

这使得函数的返回类型完全变为borked,因为parameters捕获组将会接受这个:

ByVal foo As Integer) As Variant(

我知道为什么它正在发生 - 因为我的正则表达式假设最后一个大括号是划分parameters捕获组的那个。< / p>

有没有办法修复我的正则表达式来改变它,而不会影响性能太多?

问题在于这是一个有效的签名:

Public Function DoSomething(foo As Integer, ParamArray bar()) As Variant()

我有另一个单独的正则表达式来处理单个参数,它会很好用......如果这个没有与数组返回类型混淆。

这就是我得到的:

enter image description here

我需要的是一个parameters组,它不包含) As Variant(部分,就像返回类型不是数组时一样:

enter image description here

1 个答案:

答案 0 :(得分:18)

你走了......

(?:(?<accessibility>Friend|Private|Public)\s)?(?:(?<kind>Sub|Function|Property\s(Get|Let|Set)))\s(?<identifier>(?:[a-zA-Z][a-zA-Z0-9_]*)|(?:\[[a-zA-Z0-9_]*\]))\((?<parameters>(?:\(\)|[^()])*)?\)(?:\sAs\s(?<reference>(((?<library>[a-zA-Z][a-zA-Z0-9_]*))\.)?(?<identifier1>([a-zA-Z][a-zA-Z0-9_]*)|\[[a-zA-Z0-9_]*\]))(?<array>\((?<size>(([0-9]+)\,?\s?)*|([0-9]+\sTo\s[0-9]+\,?\s?)+)\))?)?

DEMO

您的原始正则表达式有哪些更改?

我刚刚将原始正则表达式中的\((?<parameters>.*)?\)部分更改为\((?<parameters>(?:\(\)|[^()])*)?\)。也就是说,您的模式中的.*将与最后一个)符号进行贪婪匹配,但此(?:\(\)|[^()])*匹配()部分或任何不属于(的字符或)零次或多次。所以这匹配foofoo()bar ..

等字符串