Superpower: match a string with parser only if it begins a line

大兔子大兔子 提交于 2019-12-04 06:22:17

问题


When parsing in superpower, how to match a string only if it is the first thing in a line?

For example, I need to match the A colon in "A: Hello Goodbye\n" but not in "Goodbye A: Hello\n"


回答1:


Using your example here, I would change your ActorParser and NodeParser definitions to this:

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;

I feel like there is a bug with Superpower, as I'm not sure why in the NodeParser I had to put a Try() on the first parser when chaining it with an Or(), but it would throw an error if I didn't add it.

Also, your validation when checking input[1] is incorrect (probably just a copy paste issue). It should be checking against "Goodbye A: Hello" and not "Hello A: Goodbye"




回答2:


Unless RegexOptions.Multiline is set, ^ matches the beginning of a string regardless of whether it is at the beginning of a line.

You can probably use inline (?m) to turn on multiline:

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



回答3:


I have actually done something similar, but I do not use a Tokenizer.

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) });

I have not tested this, just wrote it out by memory. The above parser should have the following:

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


来源:https://stackoverflow.com/questions/52706549/superpower-match-a-string-with-parser-only-if-it-begins-a-line

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!