【问题标题】:How to tell which group matched when using as a lexer?用作词法分析器时如何判断哪个组匹配?
【发布时间】:2013-11-20 03:29:58
【问题描述】:

我使用 .NET 正则表达式作为简单的词法分析器:

var pattern = new Regex("(?<if>if)|(?<then>then)|(?<int>\-?\d+)...");
var tokens = pattern.Matches(input).Cast<Match>()
    .Select(m => new Token { Text = m.Value, Type = TokenTypes.First(tt => !string.IsNullOrEmpty(m.Groups[tt].Value) });

匹配后,我可以通过遍历所有代表令牌类型的命名组并找到实际匹配的组来确定每个令牌的类型。不过,这似乎有点缓慢和笨拙。我想知道:有没有更好的方法来使用 .NET Regex API 查找所有匹配的组?

【问题讨论】:

    标签: c# .net regex capturing-group


    【解决方案1】:

    我真的不认为有任何问题。但是,如果您的组都不允许空字符串,您可以使用Success 属性而不是检查组的Value。这基本上是你已经拥有的,但在我看来这似乎更优雅一点:

    var tokens = pattern.Matches(input).Cast<Match>()
        .Select(m => new Token { Text = m.Value, Type = TokenTypes.First(tt => m.Groups[tt].Success) });
    

    或者在查询语法中:

    var tokens = 
        from Match m in pattern.Matches(input)
        select new Token 
        { 
            Text = m.Value, 
            Type = TokenTypes.First(tt => m.Groups[tt].Success) 
        };
    

    【讨论】:

    • 这种方法可能与我的方法具有相同的性能影响。对?目前,我发现这个确定标记类型的过程实际上是我的词法分析器中最慢的部分之一。您是否断言在当前 Regex API 的情况下没有其他方法?
    • @ChaseMedallion 充其量只能是边际性能提升。我可以提出的唯一其他建议是使用组号而不是名称,因为每次都必须调用 GroupNumberFromName 来按名称查找每个组。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-18
    • 1970-01-01
    • 2019-10-06
    • 1970-01-01
    相关资源
    最近更新 更多