c# - Pidgin 消耗任何字符直到匹配并且不消耗第二个匹配
问题描述
我尝试将各种输入字符串解析为对象列表,其中一些输入可能包含标点符号。
在使用字符串块或其他东西之前,我不会成功。
测试输入字符串是否正常工作:
var inputs = new List<string>{
"prefix{{test='5'}}middle{{'test string'}}{{'test1'}}postfix",
"{{test='5'}}middle{{'test string'}}{{'test1'}}postfix",
"{{test='5'}}middle{{'test string'}}{{'test1'}}",
}
然而,这一切都包含字母和数字。所以这个不起作用:
var notWorkingInput= ".?n6y{{test='5'}}+*854d{{'test string'}}{{'test1'}}ret0}";
的预期结果notWorkingInput
是这样的:
- 文本对象 (
Name = ".?n6y"
) - Test2 对象 (
Name = "test", Value="5"
) - 文本对象 (
Name = "+*854d"
) - Test1 对象 (
Name = "test string"
) - Test1 对象 (
Name = "test1"
) - 文本对象 (
Name = "ret0}"
)
我使用Pidgin解析库。
完整的工作代码:
public class TestParser {
private static readonly Parser<char, string> ObjectStart = String("{{");
private static readonly Parser<char, string> ObjectEnd = String("}}");
private static readonly Parser<char, string> Equal = String("=");
private static Parser<char, T> Tok<T>(Parser<char, T> token) => Try(token).Before(SkipWhitespaces);
private static Parser<char, string> Tok(string token) => Tok(String(token));
private static readonly Parser<char, string> StringLiteralDouble = Tok(Try(String("\"\"")).ThenReturn('"')
.Or(Token(c => c != '"'))
.ManyString()
.Between(Char('"')));
private static readonly Parser<char, string> StringLiteralSingle = Tok(Try(String("''")).ThenReturn('\'')
.Or(Token(c => c != '\''))
.ManyString()
.Between(Char('\'')));
private static readonly Parser<char, string> StringLiteral = Tok(OneOf(StringLiteralDouble, StringLiteralSingle));
private static readonly Parser<char, ITest> Test1Statement = Tok(StringLiteral.Between(Whitespaces).Between(ObjectStart, ObjectEnd))
.Select<ITest>(s => new Test1(s));
private static readonly Parser<char, ITest> Test2Statement = Tok(Letter.ManyString()).Before(Tok(Equal))
.Then(OneOf(Num.Select<dynamic>(s => s), Real.Select<dynamic>(s => s), StringLiteral.Select<dynamic>(s => s), LetterOrDigit.ManyString().Select<dynamic>(s => s)), (s, v) => new Test2(s, v)).Between(ObjectStart, ObjectEnd)
.Select<ITest>(s => s);
private static readonly Parser<char, ITest> TextStatement = LetterOrDigit.AtLeastOnceString().Select<ITest>(s => new Text(s));
private static readonly Parser<char, ITest> Statement = OneOf(Test1Statement, Test2Statement, TextStatement);
private static readonly Parser<char, IEnumerable<ITest>> Statements = Statement.Many();
public static Result<char, IEnumerable<ITest>> Parse(string input) => Statements.Parse(input);
}
public interface ITest {
string Name { get; }
}
public class Test1 : ITest {
public string Name { get; }
public Test1(string name) {
Name = name;
}
}
public class Test2 : ITest {
public string Name { get; }
public dynamic Value { get; }
public Test2(string name, dynamic value) {
Name = name;
Value = value;
}
}
public class Text : ITest {
public string Name { get; }
public Text(string name) {
Name = name;
}
}
更新:
我测试AnyCharExcept('{', '}')
。实际上,它正在工作,但现在是单括号问题。
更新 2:
如果可能的话,添加类似的东西AnyExcept
也会很好。
更新 3:
图书馆的作者建议我使用Any.Until(Lookahead(String("{{")).Or(End))
,但它不起作用。
解决方案
推荐阅读
- c++ - 'struct' 之前的预期主表达式
- jmeter - 如何在 Jmeter 中处理刷新令牌
- wix - Wix Toolset 重大升级并没有完全删除以前的版本
- vbscript - 如何更改vbscript消息框的任务栏图标?
- salesforce - HTML 显示在 aura 组件中
- android - 如何在 Kotlin 中向 android 工具栏添加额外的菜单
- python - 我怎样才能使这些功能按照 OOP 原则工作?
- node.js - 将多个图像从后端(节点)发送到前端(反应)
- javascript - 从javascript调用代码内部的方法时如何显示错误消息
- python - Python数据框将每个单元格中的列数据重复为列表