1

I'm trying to parse a string that contains text interspersed with stars:

var input = "*This is the first part*This is the second part";

I want to extract any text between stars and the text after the last star. The string doesn't end in a star, or a newline.

I've written a parser with Sprache to try and achieve this:

Parser<string> thingAfterStarParser = (
    from open in Parse.String("*")
    from rest in Parse.AnyChar.Many().Text()
    select rest
);

var result = thingAfterStarParser.AtLeastOnce().Parse(input);

But result only ends up with one element, instead of two. I think it's because rest is parsing all the way to the end of the input.

How can I tell the parser to parse until stars or the end of the input? Any help would be much appreciated! Thank you

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
Paul
  • 1,897
  • 1
  • 14
  • 28

1 Answers1

3

I think it's because rest is parsing all the way to the end of the input.

You're right about that. Parse.AnyChar will not stop at next *. You can do it like this:

public class UnitTest1
{
    readonly ITestOutputHelper output;

    public UnitTest1(ITestOutputHelper output) => this.output = output;

    [Fact]
    public void Split()
    {
        const string input = "*This is the first part*This is the second part";

        var thingAfterStarParser = 
            from open in Parse.String("*")
            from rest in Parse.AnyChar.Except(Parse.Char('*')).Many().Text()
            select rest;

        var result = thingAfterStarParser.AtLeastOnce().Parse(input);

        foreach (var message in result)
        {
            output.WriteLine(message);
        }
    }
}
asgerhallas
  • 16,890
  • 6
  • 50
  • 68