Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在C中正则表达式匹配带括号的模式#_C#_Regex - Fatal编程技术网

C# 如何在C中正则表达式匹配带括号的模式#

C# 如何在C中正则表达式匹配带括号的模式#,c#,regex,C#,Regex,背景:我正在进行一些复杂的代码生成,需要提取C#接口文件中的方法。我不能简单地使用反射,因为这段代码将提供一个T4模板,而该模板将没有编译后的代码进行反射。因此,我正在尝试解析。我可以很容易地创建自己的解析器,但如果有正则表达式解决方案就好了 问题:使用C#的正则表达式库,是否存在/什么正则表达式模式会匹配下面字符串的方法声明(包括返回类型和参数) string testing = @" using System; using System.Collections.Gen

背景:我正在进行一些复杂的代码生成,需要提取C#接口文件中的方法。我不能简单地使用反射,因为这段代码将提供一个T4模板,而该模板将没有编译后的代码进行反射。因此,我正在尝试解析。我可以很容易地创建自己的解析器,但如果有正则表达式解决方案就好了

问题:使用C#的正则表达式库,是否存在/什么正则表达式模式会匹配下面字符串的方法声明(包括返回类型和参数)

    string testing = @"
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    namespace ConsoleApplication1
    {
        public interface Service
        {
            int Test1(int a);

            int Test2(int a, int b);

            int Test3(
                int a,
                int b);

            int Test4(out int a);
        }
    }
    ";
我想要的正则表达式模式应该有四个匹配项:

  • “int Test1(int a);”
  • int Test2(int a,int b)
  • “inttest3(inta,intb);”[注意:#3将是多行]
  • “int Test4(out int a);”
  • 解决方案尝试:这里可能是我迄今为止最接近正则表达式解决方案的地方:

    string WhiteSpacePattern = @"\s+";
    string PossibleWhiteSpacePattern = @"\s*";
    string CsharpWordPattern = @"[a-zA-Z_]+";
    string ParenthesesPattern = @"[(][\s\S]*?[)]";
    
    string DoubleCsharpWordPattern = CsharpWordPattern + WhiteSpacePattern + CsharpWordPattern;
    string MethodDeclarationPattern =
        DoubleCsharpWordPattern +
        PossibleWhiteSpacePattern +
        ParenthesesPattern;
    
    模式使用示例:

    MatchCollection tests = Regex.Matches(testing, MethodDeclarationPattern);
    
    单独的模式工作得很好(CsharpWordPattern、圆括号模式、空白模式和可能的空白模式)。但是,当我将它们全部放在一个模式(MethodDeclarationPattern)中时,整个模式失败了


    MethodDeclarationPattern或my usage example需要如何更改才能开始匹配接口代码中的方法声明?

    要匹配文本参数,请使用反斜杠转义:

    string ParenthesesPattern = @"\([\s\S]*?\)";
    
    该正则表达式片段匹配一对匹配的括号,括号之间有可选的空格。你把它放在整个正则表达式的末尾

    您的完整串联正则表达式如下所示:

    [a-zA-Z_]+\s+[a-zA-Z_]+\s*[(][\s\S]*?[)]
    
    "int foo ()"
    
    string openParenPattern = @"\([\s\S]*?";
    string closeParenPattern = @"[\s\S]*?\)";
    
    标识符,空格,标识符,打开参数,空格,关闭参数

    要使其匹配,方法声明必须如下所示:

    [a-zA-Z_]+\s+[a-zA-Z_]+\s*[(][\s\S]*?[)]
    
    "int foo ()"
    
    string openParenPattern = @"\([\s\S]*?";
    string closeParenPattern = @"[\s\S]*?\)";
    
    我相信你会在这样的事情上取得更好的成功:

    [a-zA-Z_]+\s+[a-zA-Z_]+\s*[(][\s\S]*?[)]
    
    "int foo ()"
    
    string openParenPattern = @"\([\s\S]*?";
    string closeParenPattern = @"[\s\S]*?\)";
    
    从概念上讲,您真正需要的是以下内容(省去空间——不需要把它弄得乱七八糟):

  • 标识符
  • 标识符
  • 开放式paren
  • ((参考| out)?标识符逗号)*
  • ((参考| out)?标识符)
  • 关闭paren
  • 我想你知道所有的语法。您将拥有嵌套的组。看着它,我真的开始对你的想法产生兴趣了,你把子正则表达式放在字符串变量中,然后把它们连接起来

    以下代码匹配测试字符串中的所有四个方法声明:

    //  This has one bug: It matches "int foo(int a,)"
    //  Somebody good with regexes could fix that. 
    var methodPattern =
        //  return type
            identPattern + spacePattern
        //  method name
        + identPattern + spacePattern
        //  open paren
        + openParenPattern + spacePattern
        //  Zero or more parameters followed by commas
        + "(" + paramPattern + spacePattern + "," + spacePattern + ")*" + spacePattern
        //  Final (or only) parameter not followed by a comma
        + "(" + paramPattern + spacePattern + ")?" + spacePattern
        //  Close paren
        + closeParenPattern;
    

    要匹配文字参数,请使用反斜杠将其转义:

    string ParenthesesPattern = @"\([\s\S]*?\)";
    
    该正则表达式片段匹配一对匹配的括号,括号之间有可选的空格。你把它放在整个正则表达式的末尾

    您的完整串联正则表达式如下所示:

    [a-zA-Z_]+\s+[a-zA-Z_]+\s*[(][\s\S]*?[)]
    
    "int foo ()"
    
    string openParenPattern = @"\([\s\S]*?";
    string closeParenPattern = @"[\s\S]*?\)";
    
    标识符,空格,标识符,打开参数,空格,关闭参数

    要使其匹配,方法声明必须如下所示:

    [a-zA-Z_]+\s+[a-zA-Z_]+\s*[(][\s\S]*?[)]
    
    "int foo ()"
    
    string openParenPattern = @"\([\s\S]*?";
    string closeParenPattern = @"[\s\S]*?\)";
    
    我相信你会在这样的事情上取得更好的成功:

    [a-zA-Z_]+\s+[a-zA-Z_]+\s*[(][\s\S]*?[)]
    
    "int foo ()"
    
    string openParenPattern = @"\([\s\S]*?";
    string closeParenPattern = @"[\s\S]*?\)";
    
    从概念上讲,您真正需要的是以下内容(省去空间——不需要把它弄得乱七八糟):

  • 标识符
  • 标识符
  • 开放式paren
  • ((参考| out)?标识符逗号)*
  • ((参考| out)?标识符)
  • 关闭paren
  • 我想你知道所有的语法。您将拥有嵌套的组。看着它,我真的开始对你的想法产生兴趣了,你把子正则表达式放在字符串变量中,然后把它们连接起来

    以下代码匹配测试字符串中的所有四个方法声明:

    //  This has one bug: It matches "int foo(int a,)"
    //  Somebody good with regexes could fix that. 
    var methodPattern =
        //  return type
            identPattern + spacePattern
        //  method name
        + identPattern + spacePattern
        //  open paren
        + openParenPattern + spacePattern
        //  Zero or more parameters followed by commas
        + "(" + paramPattern + spacePattern + "," + spacePattern + ")*" + spacePattern
        //  Final (or only) parameter not followed by a comma
        + "(" + paramPattern + spacePattern + ")?" + spacePattern
        //  Close paren
        + closeParenPattern;
    

    您可以利用T4中Roslyn的强大功能为您进行解析。您可以利用T4中Roslyn的强大功能为您进行解析。这就是在.NET正则表达式中匹配文字参数的方法。代码所做的是在开头匹配一对paren,在结尾匹配另一对paren。在我看来,这并不是你需要匹配的,我认为它与任何东西都不匹配这一事实有利于我的解释。我也喜欢字面版本。但不管怎样,“括号模式”已经在起作用了。问题是,当我形成最终的模式“MethodDeclarationPattern”时,完整的模式失败了。因此,将模式合并在一起会导致失败。即使我使用文字版本,它仍然失败。谢谢更新。我同意你的解决方案是可行的,但它似乎比必要的复杂得多。如果我必须为多个参数和/或out参数包含一些温和的逻辑,那么我宁愿自己完成整个解析,完全忽略正则表达式。在将来,我可能需要包括像带有泛型参数的类型这样的东西,这只会使正则表达式变得更加荒谬所以我可能会自己解析它。谢谢:)@ZacharyPatten刚刚添加了更新的示例代码,用于查找所有方法声明。不知道这有什么复杂的。哇,老兄!这非常有效。谢谢我将试着回顾一下你的例子,找出我做错了什么。我可能只是对正则表达式的工作原理有一些错误的假设。这就是在.NET正则表达式中匹配文字参数的方式。代码所做的是在开头匹配一对paren,在结尾匹配另一对paren。在我看来,这并不是你需要匹配的,我认为它与任何东西都不匹配这一事实有利于我的解释。我也喜欢字面版本。但不管怎样,“括号模式”已经在起作用了。问题是,当我形成最终的模式“MethodDeclarationPattern”时,完整的模式失败了。因此,将模式合并在一起会导致失败。即使我使用文字版本,它仍然失败。谢谢更新。我同意你的解决方案是可行的,但它似乎比必要的复杂得多。如果我必须为多个参数和/或输出参数包含一些温和的逻辑,那么