尝试用相似的 open/close/delimiter 个字符构建 TextParser<string[]>

Trying to build TextParser<string[]> with alike open/close/delimiter characters

我正在使用 SuperPower 库构建解析器。

这是我要解析的源输入示例:

|ABC|xyz|1 3|~~~|

new string[]{"ABC", "xyz", "1 3", "~~~"}

我认为我遇到的问题是我的分隔符与我的 ClosingPipe 字符相同。

我应该如何构建这个 TextParser<string[]>

以下是一些适合您的解析器:

public static TextParser<char> Pipe =>
    from c in Character.EqualTo('|')
    select c;

public static TextParser<string> Content =>
    from c in Character.Except('|').Many()
    select new string(c);

public static TextParser<string[]> Parser =>
    from openingPipe in Pipe
    from content1 in Content
    from closingPipe in Pipe
    from contents in Content.ManyDelimitedBy(Pipe)
    select new[] { content1 }
        .Concat(contents.Take(contents.Length - 1)) // remove the empty string on the end
        .ToArray();

然后像这样使用它:

string[] result = Parser.Parse("|ABC|xyz|1 3|~~~|");

result应该是{ "ABC", "xyz", "1 3", "~~~" }

想法是解析开始管道,首先是内容,然后是结束管道,然后因为(我假设)其余的分隔符数量可以改变,您可以使用 Superpower 的内置方法 ManyDelimitedBy 来解析尽可能多的其他内容片段,用竖线分隔。但是由于您的输入总是在末尾有一个管道,因此 ManyDelimitedBy 将在 contents 数组的末尾留下一个空字符串,我在返回最终输出之前将其删除。

编辑

这里有一种方法可以做到这一点而不必切断空字符串:

public static TextParser<string> ExtraContent =>
    from content in Content
    from pipe in Pipe
    select content;

public static TextParser<string[]> Parser2 =>
    from openingPipe in Pipe
    from content1 in Content
    from closingPipe in Pipe
    from contents in ExtraContent.Many()
    select new[] { content1 }.Concat(contents).ToArray();