修改正则是包括逗号
modify regex to include comma
我有以下字符串:
arg1('value1') arg2('value '')2') arg3('user'~!@#$%^&*_~!@#$%^&"*_-=+[{]}|;:<.>?21')
提取值的正则是:
boost::regex re_arg_values("('[^']*(?:''[^']*)*'[^)]*)");
上面的正则拨号正确提取值。但是,当我包括一个逗号时,代码会失败。例如:
arg1('value1') arg2('value '')2') arg3('user'~!@#$%^&*_~!@#$%^&"*_-=+[{]}|;:<.>?21**,**')
我应该如何修改此正则以包括逗号?供参考。该值可以包含空格,特殊字符以及选项卡。代码在CPP中。
预先感谢。
我在这里不使用正则态度。
目标必须是解析值,毫无疑问它们将具有有用的值,您需要解释。
我会设计一个数据结构:
#include <map>
namespace Config {
using Key = std::string;
using Value = boost::variant<int, std::string, bool>;
using Setting = std::pair<Key, Value>;
using Settings = std::map<Key, Value>;
}
为此,您可以使用Boost Spirit编写1:1 A解析器:
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/adapted/std_pair.hpp>
namespace Parser {
using It = std::string::const_iterator;
using namespace Config;
namespace qi = boost::spirit::qi;
using Skip = qi::blank_type;
qi::rule<It, std::string()> quoted_ = "'" >> *(
"'" >> qi::char_("'") // double ''
| '' >> qi::char_ // any character escaped
| ~qi::char_("'") // non-quotes
) >> "'";
qi::rule<It, Key()> key_ = +qi::char_("a-zA-Z0-9_"); // for example
qi::rule<It, Value()> value_ = qi::int_ | quoted_ | qi::bool_;
qi::rule<It, Setting(), Skip> setting_ = key_ >> '(' >> value_ >> ')';
qi::rule<It, Settings()> settings_ = qi::skip(qi::blank) [*setting_];
}
请注意此
如何- 正确解释非弦乐值
- 指定键的样子,并解析它们
- 解释字符串Escapes,因此地图中的
Value
包含"真实"字符串,在Un-Escaping之后 - 忽略空格外部值(如果您想忽略新线,也可以使用
space_type
,也可以使用)
)
您可以像以下方式使用:
int main() {
std::string const input = R"( arg1('value1') arg2('value '')2') arg3('user'~!@#$%^&*_~!@#$%^&"*_-=+[{]}|;:<.>?21**,**'))";
Config::Settings map;
if (parse(input.begin(), input.end(), Parser::settings_, map)) {
for(auto& entry : map)
std::cout << "config setting {" << entry.first << ", " << entry.second << "}n";
}
}
哪个打印
config setting {arg1, value1}
config setting {arg2, value ')2}
config setting {arg3, user'~!@#$%^&*_~!@#$%^&"*_-=+[{]}|;:<.>?21**,**}
实时演示
活在coliru
#include <boost/spirit/include/qi.hpp>
#include <map>
#include <boost/fusion/adapted/std_pair.hpp>
namespace Config {
using Key = std::string;
using Value = boost::variant<int, std::string, bool>;
using Setting = std::pair<Key, Value>;
using Settings = std::map<Key, Value>;
}
namespace Parser {
using It = std::string::const_iterator;
using namespace Config;
namespace qi = boost::spirit::qi;
using Skip = qi::blank_type;
qi::rule<It, std::string()> quoted_ = "'" >> *(
"'" >> qi::char_("'") // double ''
| '' >> qi::char_ // any character escaped
| ~qi::char_("'") // non-quotes
) >> "'";
qi::rule<It, Key()> key_ = +qi::char_("a-zA-Z0-9_"); // for example
qi::rule<It, Value()> value_ = qi::int_ | quoted_ | qi::bool_;
qi::rule<It, Setting(), Skip> setting_ = key_ >> '(' >> value_ >> ')';
qi::rule<It, Settings()> settings_ = qi::skip(qi::blank) [*setting_];
}
int main() {
std::string const input = R"( arg1('value1') arg2('value '')2') arg3('user'~!@#$%^&*_~!@#$%^&"*_-=+[{]}|;:<.>?21**,**'))";
Config::Settings map;
if (parse(input.begin(), input.end(), Parser::settings_, map)) {
for(auto& entry : map)
std::cout << "config setting {" << entry.first << ", " << entry.second << "}n";
}
}
奖金
为了进行比较,这是"相同",但使用正则:
活在coliru
#include <boost/regex.hpp>
#include <boost/range/iterator_range.hpp>
#include <iostream>
#include <map>
namespace Config {
using Key = std::string;
using RawValue = std::string;
using Settings = std::map<Key, RawValue>;
Settings parse(std::string const& input) {
Settings settings;
boost::regex re(R"((w+)(('.*?')))");
auto f = boost::make_regex_iterator(input, re);
for (auto& match : boost::make_iterator_range(f, {}))
settings.emplace(match[1].str(), match[2].str());
return settings;
}
}
int main() {
std::string const input = R"( arg1('value1') arg2('value '')2') arg3('user'~!@#$%^&*_~!@#$%^&"*_-=+[{]}|;:<.>?21**,**'))";
Config::Settings map = Config::parse(input);
for(auto& entry : map)
std::cout << "config setting {" << entry.first << ", " << entry.second << "}n";
}
打印
config setting {arg1, 'value1'}
config setting {arg2, 'value ''}
config setting {arg3, 'user'~!@#$%^&*_~!@#$%^&"*_-=+[{]}|;:<.>?21**,**'}
注意:
- 它不再解释并转换任何值
- 它不再处理逃逸
- 它需要对BOOST_REGEX的额外运行时库
相关文章:
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 独立读取-修改-写入顺序
- 从矢量<无符号字符>转换为字符* 包括垃圾数据
- Windows 10-使用gtkmm-3.0库和g++[包括再现]的分段故障
- 当系统的卷被修改时,如何修改WASAPI环回捕获卷
- 为什么 cmake 许可证<>样式不包括?
- 修改函数中的指针(将另一个指针作为参数传递)
- 为什么我可以通过引用修改常量返回
- 对于结构,表达式必须是可修改的ivalue
- QML:修改在不同QML文件(而非main.QML)中定义的子对象的属性
- 计算平均值,不包括上次得分
- 为什么不能修改对象中的值?另外,我如何改进此链表?
- 修改创建帐户程序
- 我应该如何修改此代码以使用给定字符串中的字母打印菱形图案
- 从多个源构造一个对象,包括一个对象向量
- 如何从子成员函数修改父公共成员变量
- 修改 VS Code 中的默认C++代码段
- 为什么在我的函数类型后使用引用运算符 (&) 允许我修改它返回的值?
- 修改正则是包括逗号
- 我如何确保修改.H文件时,使用Visual Studio 2008将包括其在内的.cc文件自动编译