【问题标题】:Case-insensitive keywords with boost::spirit::lex带有 boost::spirit::lex 的不区分大小写的关键字
【发布时间】:2016-10-21 11:24:22
【问题描述】:
有没有办法以不区分大小写的方式识别特定模式?
例如如果我有
literal_bool = L"True|False";
this->self.add(literal_bool, TokenId_LiteralBool);
如何匹配true、TRUE、tRuE,同时避免为每个关键字写[Tt][Rr][Uu][Ee]?
【问题讨论】:
标签:
c++
boost
boost-spirit
case-insensitive
boost-spirit-lex
【解决方案1】:
Regular expressions supported by boost::spirit::lex 包含区分大小写的控件:
(?r-s:pattern)
在解释模式时应用选项'r'并省略选项's'。
选项可以是零个或多个字符'i' 或's'。 'i'
表示不区分大小写。 '-i' 表示区分大小写。 's' 更改
'.' 语法的含义以匹配任何单个字符。
'-s' 改变 '.' 的含义以匹配任何字符,除了
'\n'。
因此你可以这样写:
literal_bool = L"(?i:true|false)";
this->self.add(literal_bool, TokenId_LiteralBool);
原答案
引入一个使模式不区分大小写的函数:
literal_bool = L"True|False";
this->self.add(make_case_insensitive(literal_bool), TokenId_LiteralBool);
常规(非宽)字符串的实现:
std::string make_case_insensitive(const std::string& s)
{
std::string r;
std::string cC = "[xX]";
for(char c : s)
{
if ( std::isalpha(c) )
{
cC[1] = std::tolower(c);
cC[2] = std::toupper(c);
r += cC;
}
else
r += c;
}
return r;
}