以下是一些适合您的解析器:
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();