You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用boost::spirit::x3编写通用字符串分组解析规则遇问题

问题描述

我正尝试使用boost::spirit::x3编写符合需求的通用解析规则,需求如下:

  • 输入"string,string",输出[string, string]
  • 输入"string.string,string",输出[string.string, string]
  • 输入"string.0.string.1.string,string",输出[string.0.string.1.string, string]

我尝试了两条规则,但都无法满足需求:

  1. auto myRule = +x3::lexeme[ +x3::alnum >> -x3::char_('.')] % +x3::char_(',');
    我的理解是:+x3::alnum >> -x3::char_('.') 允许string、string.string等格式,直到遇到% +x3::char_(',')分隔符
  2. auto myRule = +x3::alnum >> +x3::lexeme[ +x3::alnum >> -x3::char_('.')] % +x3::char_(',');
    我的理解是:+x3::alnum匹配基础字符串,后续规则匹配带点的格式,直到遇到分隔符

请问我哪里出错了?

问题分析与解决

你的规则错误在于对boost::spirit::x3组合逻辑的理解偏差:

  1. 第一条规则里,+x3::alnum >> -x3::char_('.')的逻辑是先匹配一串字母数字,然后可选匹配一个点,再被+包裹后,会变成重复这个组合——这会导致它匹配类似string.string.(末尾带点)的内容,而且遇到逗号时无法正确终止,因为它会尝试继续匹配字母数字,而非识别逗号作为分隔符。

  2. 第二条规则的结构完全错误,+x3::alnum >> +[...] % ','的逻辑是先匹配一串字母数字,然后必须匹配多个被逗号分隔的[...]规则,这和你要解析的“逗号分隔的多个带点字符串”的结构完全不符。

正确的规则可以这样写:

// 允许点在任意位置的简单版本
auto element = x3::lexeme[ +(x3::alnum | x3::char_('.')) ];
auto myRule = element % x3::char_(',');

如果需要避免元素开头或结尾出现点(更贴合你的示例需求),可以用更严谨的版本:

auto element = x3::lexeme[ x3::alnum >> *(x3::char_('.') >> x3::alnum) ];
auto myRule = element % x3::char_(',');

解释:

  • element规则:
    • 简单版本直接匹配任意字母数字和点的组合,适合允许点出现在任意位置的场景;
    • 严谨版本确保元素以字母数字开头,后续是任意数量的“点+字母数字”组合,完全符合你给出的示例格式。
  • myRule规则:用%分隔符,匹配多个element,用逗号分隔,正好对应你需要的输入格式。

内容的提问来源于stack exchange,提问作者proton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 10:43:25