如果参数跨多行拆分,如何使用RegEx获取方法名

本文关键字:RegEx 何使用 获取 方法 参数 拆分 如果 | 更新日期: 2023-09-27 18:02:07

我有一堆c#源文件,我需要分析VS的超大尺寸,我正在努力与一个特定的情况:

    public static bool InsertNote(string TableName, string TableKey, string DocType, string InsuredKey, string SubmissionKey,
                                    string Staff, string DefaultAction, string DisplayKey, FileType FileType, string IFSFileName,
                                    string IFSFolder, string IFSTimeStamp, string Subject, string Notation, NoteType NoteType,
                                    //string Company, string NoteCategory, ref OracleConnection Connection)
                                    string Company, string NoteCategory, string DocumentName, ref SqlConnection Connection)
    {

我认为这个RegEx应该能够找到它:

    private static readonly Regex MethodNamesExtractor = new Regex(@"^.*('S*)'({1}.*ref's*SqlConnection", RegexOptions.Multiline | RegexOptions.Compiled);

但它没有。我错过了什么?

如果参数跨多行拆分,如何使用RegEx获取方法名

.默认不匹配换行符。您可以使用RegexOptions来解决这个问题。单行模式:

private static readonly Regex MethodNamesExtractor = new Regex(@"^.*('S*)'({1}.*ref's*SqlConnection", RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.Compiled);

Multiline选项使^$分别匹配一行的开头和结尾,而不是匹配整个字符串的开头和结尾。这可能有点令人困惑,但事实就是如此!您可以使用与(?s)相同的内联修饰符。我将在随后的正则表达式中使用它,并删除Multiline模式,因为它没有被使用。

但这不是唯一的问题。.*不会贪婪地匹配,这意味着它会在'S*有机会匹配之前尽可能多地匹配。您可以通过使.*懒惰来解决这个问题,即通过向其添加?,或者简单地删除它,因为它无论如何都不会做太多事情。另外,{1}是多余的,因为默认的量词是重复一次。另外,开始的^.*没有做太多的事情,你可以安全地删除它:

private static readonly Regex MethodNamesExtractor = new Regex(@"(?s)('S*)'(.*ref's*SqlConnection", RegexOptions.Compiled);

现在是棘手的部分:如果你现在试图从许多方法中匹配几个方法名,上面的正则表达式将只匹配一个。假设您试图从两个方法中获取方法名称,第一个方法没有req SqlConnection部分,而第二个方法有。好吧,你得到这个。

要解决这个问题,您可能希望通过使用[^)]*.*限制为一个被否定的类。您将注意到,使用此方法不会给您任何匹配,这是因为方法中的注释部分在req SqlConnection部分出现之前具有)。那么,您可以允许像这样注释行:

"(?s)('S*)'((?:[^)]|//[^'r'n]*'))*ref's*SqlConnection"

如果在参数中没有任何'false'双正斜杠或父括号。为了允许注释块,正则表达式将变得更长,很明显…(如果你想在参数中允许父元素,甚至更长)

"(?s)('S*)'((?:[^)]|//[^'r'n]*')|/'*(?:(?!'*/).)*'*/)*ref's*SqlConnection"

那么,总结一下,使用专门的解析器来解析编程语言可能会更好。

你需要在星号后面加一个问号

private static readonly Regex MethodNamesExtractor = new Regex(@"^.*?('S*)'({1}.*?ref's*SqlConnection", RegexOptions.Singleline | RegexOptions.Compiled);

否则星号将充当贪婪量词。

http://regex101.com/r/qG5lD3

我想如果你添加RegexOptions.Singleline,它会做你想要的。这是在regex101.com

所以请尝试以下操作(从regex101样式定义动态翻译):

private static readonly Regex MethodNamesExtractor = new Regex(@"^.*('S*)'({1}.*ref's*SqlConnection", RegexOptions.Singleline | RegexOptions.Compiled);

原因:Multiline^ &的解释方式有关。另一方面,Singleline表示.匹配换行符,这是您想要的,因为您的测试文本跨多行。