Superpower: сопоставлять строку с парсером, только если она начинается строкой - PullRequest
0 голосов
/ 08 октября 2018

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

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

Ответы [ 3 ]

0 голосов
/ 24 октября 2018

Используя ваш пример здесь , я бы изменил ваши 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"

0 голосов
/ 24 октября 2018

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

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"
0 голосов
/ 08 октября 2018

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

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

static TextParser<Unit> Actor { get; } =
  from start in Span.Regex(@"(?m)^[A-Za-z][A-Za-z0-9_]+:")
  select Unit.Value;
...