Как определить, какая группа соответствует при использовании в качестве лексера?

Я использую.NET Regex в качестве простого лексера:

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?

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) 
    };
Другие вопросы по тегам