Dart/Flutter用petitparser解析字符串遇大写字母预期错误求助
问题:Petitparser解析含字母的中间段失败及修改验证
问题场景
原本的Flutter/Dart代码使用Petitparser解析包含数字中间段的表达式完全正常,但将中间的数字替换为单词(如把5改成test)后,解析器抛出错误:uppercase letter expected at 1:1。尝试将digit().plus()改为word().plus()后解析恢复正常,需确认该修改是否正确。
原始可运行代码
testString = '((S|71|L || S|70|L || S|69|L || S|72|L) && (F|54|L || F|52|L || H|5|L))'; final builder = ExpressionBuilder(); final primitive = (uppercase() & char('|') & digit().plus() & char('|') & uppercase()).flatten().trim(); builder.group().primitive(primitive); builder.group() .wrapper(char('(').trim(), char(')').trim(), (l, v, r) => v); builder.group() ..left(string('&&').trim(), (a, op, b) => ['&&', a, b]) ..left(string('||').trim(), (a, op, b) => ['||', a, b]); final parser = builder.build().end(); final result = parser.parse(testString);
修改后的测试字符串
testString = '((S|71|L || S|70|L || S|69|L || S|72|L) && (F|54|L || F|52|L || H|test|L))';
解答
把digit().plus()改为word().plus()是正确的修改方式,原因如下:
- 原始的
digit().plus()仅能匹配连续数字,当中间段变为字母组成的test时,这部分解析直接失败,导致整个primitive规则匹配失败。Petitparser的错误提示有时会指向表达式起始位置,因此出现了看似偏离实际问题位置的1:1错误。 word()在Petitparser中匹配字母、数字和下划线(等价于letter() | digit() | char('_')),刚好覆盖你需要的「数字」和「单词」两种中间段场景。- 若需要更精确的匹配(比如仅允许字母数字、排除下划线),可以自定义规则:
(letter() | digit()).plus(),更贴合表达式的结构需求。
另外,你之前尝试any().plus()仍报错,是因为any()会匹配任意字符(包括后续的|),导致primitive规则中后续的char('|') & uppercase()无法匹配,最终触发错误。而word().plus()会在遇到非单词字符(如|)时停止匹配,完全符合表达式中|分隔的结构逻辑。
内容的提问来源于stack exchange,提问作者Coltuxumab
相关产品推荐
相关产品推荐

