Superpower: сопоставлять строку с парсером, только если она начинается строкой

Разбирая в супердержаве, как сопоставить строку, только если она является первой в строке?

Например, мне нужно сопоставить двоеточие A в "A: Hello Goodbye\n", но не в "Goodbye A: Hello\n"

3 ответа

Используя ваш пример здесь, я бы изменил ваш ActorParser а также NodeParser определения к этому:

public readonly static TokenListParser<Tokens, Node> ActorParser =
    from name in NameParser
    from colon in Token.EqualTo(Tokens.Colon)
    from text in TextParser
    select new Node {
        Actor = name + colon.ToStringValue(),
        Text = text
    };

public readonly static TokenListParser<Tokens, Node> NodeParser =
    from node in ActorParser.Try()
        .Or(TextParser.Select(text => new Node { Text = text }))
    select node;

Я чувствую, что есть ошибка с Superpower, так как я не уверен, почему в NodeParser Я должен был поставить Try() на первом парсере при сцеплении его с Or(), но я бы добавил ошибку, если бы я ее не добавил.

Кроме того, ваша проверка при проверке input[1] неверно (возможно, просто проблема с копированием-вставкой). Это должно быть проверка против "Goodbye A: Hello" и не "Hello A: Goodbye"

Я действительно сделал нечто подобное, но я не использую токенизатор.

private static string _keyPlaceholder;

private static TextParser<MyClass> Actor { get; } =
    Span.Regex("^[A-Za-z][A-Za-z0-9_]*:")
        .Then(x =>
             {
                 _keyPlaceholder = x.ToStringValue();
                 return Character.AnyChar.Many();
             }
         ))
    .Select(value => new MyClass { Key = _keyPlaceholder, Value = new string(value) });

Я не проверял это, просто выписал это по памяти. Вышеуказанный парсер должен иметь следующее:

myClass.Key = "A:"
myClass.Value = " Hello Goodbye"

Если не RegexOptions.Multiline установлено, ^ соответствует началу строки независимо от того, находится ли она в начале строки.

Вы можете, вероятно, использовать встроенный (?m) включить мультилинию:

static TextParser<Unit> Actor { get; } =
  from start in Span.Regex(@"(?m)^[A-Za-z][A-Za-z0-9_]+:")
  select Unit.Value;
Другие вопросы по тегам