C# 查找重新抛出的不';t通过正则表达式设置内部异常

C# 查找重新抛出的不';t通过正则表达式设置内部异常,c#,regex,C#,Regex,我试图找到所有重新抛出异常的代码,其中抛出的新异常不包含作为内部异常的原始异常。下面是一个例子: catch(DBApplicationException dbEx) { BaseApplicationException bEx = new BaseApplicationException(dbEx.Message, dbEx); bEx.MethodName = System.Reflection.Ass

我试图找到所有重新抛出异常的代码,其中抛出的新异常不包含作为内部异常的原始异常。下面是一个例子:

            catch(DBApplicationException dbEx) 
        {
            BaseApplicationException bEx = new BaseApplicationException(dbEx.Message, dbEx);
            bEx.MethodName = System.Reflection.Assembly.GetExecutingAssembly().FullName + "::" + System.Reflection.MethodBase.GetCurrentMethod().Name.ToString();
            bEx.Severity = ExceptionSeverityLevel;
            PublishingManager.Publish(bEx,"");
            throw bEx;
        }
        catch(Exception e) 
        {
            BaseApplicationException bEx = new BaseApplicationException(e.Message);
            bEx.MethodName = System.Reflection.Assembly.GetExecutingAssembly().FullName + "::" + System.Reflection.MethodBase.GetCurrentMethod().Name.ToString();
            bEx.Severity = ExceptionSeverityLevel;
            PublishingManager.Publish(bEx,"");
            throw bEx;
        }
第一个catch(catch(DBApplicationException dbEx)作为BaseApplicationException重新抛出,但正如您所见,它将消息设置为dbEx.message,然后将InnerException指定为dbEx,但第二个catch段在没有InnerException的情况下重新抛出,它只包含e.message

所以对于我的正则表达式模式,我只想找到不包含内部异常的整个catch块,现在,我使用的模式同时返回这两个catch块

以下是我的正则表达式模式:

catch((.|\n|\r)*){((.|\n|\r)*)Exception\(((?!,).)+\);((.|\n|\r)*)}
下面是我测试此场景的方法块:

public static DataSet SearchUserSessions(string username, string first, string last, string startDate, string endDate) 
    {
        DataSet ds = null;
        try 
        {
            SqlParameter [] arParms = new SqlParameter[]
            {
                new SqlParameter("@UserName", username),
                new SqlParameter("@FirstName", first),
                new SqlParameter("@LastName", last),
                new SqlParameter("@SessionStart", startDate),
                new SqlParameter("@SessionEnd", endDate)
            };

            DB db = new DB();
            ds = db.ExecuteDataset(SecurityConfig.ConnectionString, CommandType.StoredProcedure, 
                SPSearchUserSessions, (DB.Provider)SecurityConfig.ConnectionProviderType, 
                arParms); 
        }
        catch(DBApplicationException dbEx) 
        {
            BaseApplicationException bEx = new BaseApplicationException(dbEx.Message, dbEx);
            bEx.MethodName = System.Reflection.Assembly.GetExecutingAssembly().FullName + "::" + System.Reflection.MethodBase.GetCurrentMethod().Name.ToString();
            bEx.Severity = ExceptionSeverityLevel;
            PublishingManager.Publish(bEx,"");
            throw bEx;
        }
        catch(Exception e) 
        {
            BaseApplicationException bEx = new BaseApplicationException(e.Message);
            bEx.MethodName = System.Reflection.Assembly.GetExecutingAssembly().FullName + "::" + System.Reflection.MethodBase.GetCurrentMethod().Name.ToString();
            bEx.Severity = ExceptionSeverityLevel;
            PublishingManager.Publish(bEx,"");
            throw bEx;
        }
        return ds;
    }

听起来非常难维护。你能在项目中强制BaseApplicationException只能作为“包装器”抛出吗异常?然后您可以删除只接受一个字符串的构造函数,并在剩下的一个构造函数中测试内部异常是否为null。

听起来非常困难,很难维护。您能否在项目中强制BaseApplicationException仅作为“包装器”抛出异常?然后您可以删除只接受一个字符串的构造函数,并在剩下的一个构造函数中测试内部异常是否为null。

这对您的示例有效:

catch\((([^)]|\n|\r)*)\)\s*{(([^}]|\n|\r)*?)Exception\(([^,](?!\n))+?\);(([^}]|\n|\r)*)}

但我同意这不是一种可维护的解决方法,除非是一次性检查。

这与您的示例相反:

catch\((([^)]|\n|\r)*)\)\s*{(([^}]|\n|\r)*?)Exception\(([^,](?!\n))+?\);(([^}]|\n|\r)*)}

但我同意,这不是一种可维护的解决方法,除非是一次性检查。

如果我理解您要做什么,这将是非常困难的。主要原因是您试图返回整个
catch
块,这意味着您必须(至少部分)返回解析C#。这是因为catch块由
{…}
结构表示,它们可以嵌套其他
{…}
块:

catch (Exception e)
{
    if (condition)
    {
        doSomething();
    }    
}
要让正则表达式标识catch块的结尾,它必须平衡{和}符号以确保它们匹配。这在带有平衡组的.NET正则表达式中是可能的,但这将比您所期望的更复杂

我还注意到你的正则表达式是非常允许的。你使用了
(.|\n |\r)
,你并不想匹配每个字符,你所有的量词都是。这里的这一点

{((.|\n|\r)*)Exception\(((?!,).)+\);((.|\n|\r)*)}
…将实际匹配单词
catch
的第一个实例到文件中的最后一个
之间的所有内容,只要它在任何地方找到类似
Exception(blah)
的内容。事实上,
blah
可以是任何没有逗号的内容,甚至是另一个语句。
Exception();DoStuff();
理论上与之匹配

IMO,您最好的选择是在
BaseApplicationException
类上使用Visual Studio的Find Usages功能。您可以找到整个类的所有用法,然后可能会将其与
BaseApplicationException.InnerException的所有用法进行比较。如果您必须使用正则表达式,则至少可以获得99%的捕获没有嵌套
{…}
块的块(为清晰起见展开):


如上所述,这将阻塞嵌套的
{…}
块。你可以用平衡组来解决这个问题,但我想保持这个简单。

如果我理解你想做什么,这将是非常困难的。主要原因是你试图返回整个
捕获
块,这意味着你必须(至少部分)返回解析C#。这是因为catch块由
{…}
结构表示,它们可以嵌套其他
{…}
块:

catch (Exception e)
{
    if (condition)
    {
        doSomething();
    }    
}
要让正则表达式标识catch块的结尾,它必须平衡{和}符号以确保它们匹配。这在带有平衡组的.NET正则表达式中是可能的,但这将比您所期望的更复杂

我还注意到你的正则表达式是非常允许的。你使用了
(.|\n |\r)
,你并不想匹配每个字符,你所有的量词都是。这里的这一点

{((.|\n|\r)*)Exception\(((?!,).)+\);((.|\n|\r)*)}
…将实际匹配单词
catch
的第一个实例到文件中的最后一个
之间的所有内容,只要它在任何地方找到类似
Exception(blah)
的内容。事实上,
blah
可以是任何没有逗号的内容,甚至是另一个语句。
Exception();DoStuff();
理论上与之匹配

IMO,您最好的选择是在
BaseApplicationException
类上使用Visual Studio的Find Usages功能。您可以找到整个类的所有用法,然后可能会将其与
BaseApplicationException.InnerException的所有用法进行比较。如果您必须使用正则表达式,则至少可以获得99%的捕获没有嵌套
{…}
块的块(为清晰起见展开):


如上所述,这将阻塞嵌套的
{…}
块。你可以用平衡组来解决这个问题,但我想保持简单。

从你的问题:
我只想找到不包含内部异常的整个catch块
--你能澄清一下吗?我不明白你想做什么。问题是什么?从你的问题:
我只想t要找到不包含内部异常的整个catch块
——请您澄清一下,好吗?我不明白您想做什么。问题出在哪里?回答得太好了!我从来没有想过在catch块中嵌套大括号(我知道它们出现在我的代码中).我想在我的场景中,我会忽略这种可能性的发生。本文的全部目的是让我可以直接转到包含“new BaseA”的代码行