Superpower 正在尝试构建TextParser<;字符串[]>;具有相同的打开/关闭/分隔符
我正在用SuperPower库构建一个解析器 下面是我要分析的源输入示例:Superpower 正在尝试构建TextParser<;字符串[]>;具有相同的打开/关闭/分隔符,superpower,Superpower,我正在用SuperPower库构建一个解析器 下面是我要分析的源输入示例: | ABC | xyz | 1 3 | ~~~~~~ | 第一个|是开口管 最后一个|是关闭管道 第二、第三和第四个|是分隔符 最终,我希望能够在解析过程中生成此结构: 新字符串[]{“ABC”、“xyz”、“13”、“~~~”} 我想我遇到的问题是,我的分隔符字符与我的ClosingPipe字符相同 我应该如何构建这个TextParser?以下是一些适合您的解析器: public static TextParse
| ABC | xyz | 1 3 | ~~~~~~ |
- 第一个
是|
开口管
- 最后一个
是|
关闭管道
- 第二、第三和第四个
是分隔符|
- 最终,我希望能够在解析过程中生成此结构:
新字符串[]{“ABC”、“xyz”、“13”、“~~~”}
我想我遇到的问题是,我的分隔符字符与我的ClosingPipe
字符相同
我应该如何构建这个
TextParser
?以下是一些适合您的解析器:
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();
和结果
应该是{ABC”,“xyz”,“13”,“~~~”}
这个想法是先解析开始的管道,然后是内容,然后是结束的管道,然后由于(我假设)分隔符的其余部分可以更改,您可以使用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();
publicstatictextparser ExtraContent=>
从内容到内容
从管道到管道
选择内容;
公共静态TextParser解析器2=>
从管道中打开管道
从Content中的content1
从管道中关闭管道
来自ExtraContent.Many()中的内容
选择new[]{content1}.Concat(contents.ToArray();
管道之间是否允许任何字符?如果是这样的话,那么管道将如何在分隔管道之间逃逸?不,管道之间不允许有管道,因此不需要逃逸。移除末端的空字符串:这是我想出的同一个方法,但我不喜欢删除空字符串。现在我感觉没那么糟了。你也可以在开始解析之前把它切掉:)
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();