C# 如何将stacktrace行拆分为命名空间、类、方法文件和行号?

C# 如何将stacktrace行拆分为命名空间、类、方法文件和行号?,c#,regex,parsing,stack-trace,C#,Regex,Parsing,Stack Trace,C#堆栈跟踪采用以下形式: at Foo.Core.Test.FinalMethod(Doh doh) in C:\Projects\src\Core.Tests\Test.cs:line 21 at Foo.Core.Test.AnotherMethod(Bar bar) at Foo.Core.Test.AMethod() in C:\Projects\src\Core.Tests\Test.cs:line 6 at Foo.Core.Test.<>c__

C#堆栈跟踪采用以下形式:

   at Foo.Core.Test.FinalMethod(Doh doh) in C:\Projects\src\Core.Tests\Test.cs:line 21
   at Foo.Core.Test.AnotherMethod(Bar bar)
   at Foo.Core.Test.AMethod() in C:\Projects\src\Core.Tests\Test.cs:line 6
   at Foo.Core.Test.<>c__DisplayClass7.<SomeAnonDelegate>b__6(Object _) in C:\Projects\src\Core.Tests\Test.cs:line 35
在C:\Projects\src\Core.Tests\Test.cs中的Foo.Core.Test.FinalMethod(Doh-Doh)中:第21行
在Foo.Core.Test.AnotherMethod(Bar)
在C:\Projects\src\Core.Tests\Test.cs中的Foo.Core.Test.AMethod()处:第6行
在c:\Projects\src\Core.Tests\Test.c\uuu中的Foo.Core.Test.c\uuuu显示Class7.b\uuuu 6(Object\uu):第35行
如何从每一行检索名称空间、类、方法、文件和行号

  • 是否有任何现有类可以这样做
  • 如果不是,最好的方法是什么
  • 正则表达式?我如何贪婪地匹配名称空间,但保留类和方法
  • 自定义解析器

希望您能提供一些想法和意见。

如果您是从a获得此信息,那么您可以通过via和call进行循环,然后。命名空间和类可以从方法中检索

编辑
作为对第一条注释的响应(不幸的是,我们从Exception.StackTrace获得了跟踪),您可以调用构造函数

编辑

我应该链接到这个构造函数——。

我读了Austin Salonen的答案,显然更好,但我已经从正则表达式开始了。所以我还是要写

Regex r = new Regex(@"at (?<namespace>.*)\.(?<class>.*)\.(?<method>.*(.*)) in (?<file>.*):line (?<line>\d*)");
var result = r.Match(@"at Foo.Core.Test.FinalMethod(Doh doh) in C:\Projects\src\Core.Tests\Test.cs:line 21");
if (result.Success)
{
    string _namespace = result.Groups["namespace"].Value.ToString();
    string _class = result.Groups["class"].Value.ToString();
    string _method = result.Groups["method"].Value.ToString();
    string _file = result.Groups["file"].Value.ToString();
    string _line = result.Groups["line"].Value.ToString();
    Console.WriteLine("namespace: " + _namespace);
    Console.WriteLine("class: " + _class);
    Console.WriteLine("method: " + _method);
    Console.WriteLine("file: " + _file);
    Console.WriteLine("line: " + _line);
}
Regex r=新的正则表达式(@“at(?.*.\(?.*)\(?.*)\(?.*(*))在(?.*):行(?\d*)”;
var result=r.Match(@“位于C:\Projects\src\Core.Tests\Test.cs:line 21中的Foo.Core.Test.FinalMethod(Doh-Doh));
如果(结果、成功)
{
字符串_namespace=result.Groups[“namespace”].Value.ToString();
字符串_class=result.Groups[“class”].Value.ToString();
字符串_method=result.Groups[“method”].Value.ToString();
字符串_file=result.Groups[“file”].Value.ToString();
字符串_line=result.Groups[“line”].Value.ToString();
WriteLine(“名称空间:”+_名称空间);
Console.WriteLine(“类:”+\u类);
Console.WriteLine(“方法:”+_方法);
Console.WriteLine(“文件:”+\u文件);
Console.WriteLine(“行:”+_行);
}
可以将堆栈跟踪文本输出(例如,通常由Environment.StackTrace或Exception.StackTrace返回)解析回堆栈跟踪帧序列,包括以下组件:

Type
Method
Parameter types and names
File and line information, if present
它可以作为直接嵌入C#项目的

然而,它需要一些函数来指定,并且它的用法不是很明显

public static IEnumerable<TFrame> Parse<TToken, TMethod, TParameters, TParameter, TSourceLocation, TFrame>(
    string text,
    Func<int, int, string, TToken> tokenSelector,
    Func<TToken, TToken, TMethod> methodSelector,
    Func<TToken, TToken, TParameter> parameterSelector,
    Func<TToken, IEnumerable<TParameter>, TParameters> parametersSelector,
    Func<TToken, TToken, TSourceLocation> sourceLocationSelector,
    Func<TToken, TMethod, TParameters, TSourceLocation, TFrame> selector)
公共静态IEnumerable解析(
字符串文本,
Func令牌选择器,
Func方法选择器,
Func参数选择器,
Func参数选择器,
Func sourceLocationSelector,
Func选择器)

出于好奇,请参见和中的示例,您是否打算在生产环境中使用此功能?据我所知,堆栈跟踪不包括在发布模式中。查看哪些状态表示所有这些信息都是从调试符号中获得的,默认情况下,调试符号不包含在发布生成器中。@J.Tihon,说得好,但是我们在发布生成器中包含符号信息。我只是不想让您经历regex和所有的麻烦,当你最终不能真正使用它时。@J.Tihon:即使没有符号,堆栈跟踪也会从发布版本中发出,但它们缺少行号和文件名。部署时没有什么理由不发送符号。PDB不会导致显著的性能下降(这是一种常见的误解,认为它们与调试版本相关)。
异常。StackTrace
是一个
字符串
,不能传递到
StackTrace
的构造函数中(它不接受
字符串
)@adrianbanks:这的确是真的,虽然OP说他是从
Exception.StackTrace
获得的,但没有任何东西表明他无权访问Exception对象(+1,顺便说一句)。幸运的是,我确实可以访问Exception,所以这是一个很好的解决方案。不幸的是,它不会提供文件、行和列,但我想我可能没有它们也能活下去。我收回这一点,有一个重载也会提供文件信息。这在PCL中不起作用。如果解析堆栈跟踪,还必须考虑本地化。看起来不错,我很高兴你在提醒我C#允许命名匹配的同时发布了文章。出于兴趣,名称空间匹配是否会处理嵌套的名称空间,例如Ns1.Ns2.Ns3.Class.Method?是的,请尝试。但是,当字符串不包含所有部分时,我似乎遇到了问题,我是说中的
和路径。如果您在德国使用本地化的.NET运行时运行此程序会怎么样?@Lasse V.Karlsen:你说得对。但我已经用一个英文示例回答了一个问题,并用
regex
标记。我知道我的答案不够好,但我还是分享了它。我发现这个答案对我正在使用记录的异常的工具很有帮助。我已经为适当的可选文件和行支持更新了正则表达式。另外,@LasseV.Karlsen Regex很少适用于本地化字符串;这超出了这个问题的范围。