我有一个简单的文本文件,其中包含以下内容:
VALUE "foo"
ANOTHERVALUE "bar"
YETANOTHERVALUE "barbar"
第1列中的值是已知的。
我想捕获第1列和第2列中的所有内容。
我的解决方案涉及手动将第1列(已知)的所有可能值写入正则表达式字符串,但显然这不是理想的做法,因为我基本上重复代码,这不允许排序灵活:< / p>
const char* re =
"^[[:space:]]*"
"(VALUE)[[:space:]]*\"(.*)\"[[:space:]]*"
"(ANOTHERVALUE)[[:space:]]*\"(.*)\"[[:space:]]*"
"(YETANOTHERVALUE)[[:space:]]*\"(.*)\"[[:space:]]*";
答案 0 :(得分:1)
我在这里引用了评论者Igor Tandetnik,因为他几乎在评论中给出了完整的答案:
正则表达式捕获与所有子串一样多的子串 左括号表达式[...]
解决此问题的正确方法是编写与a匹配的正则表达式 单对,[...]
\s*([a-zA-Z]+)\s*"(.*?)"
注意:
\s
相当于[[:space:]]
.*?
用于在第二个"
后停止搜索,而不是字符串中的最后一个"
并重复应用,例如通过std :: regex_iterator
等效提升为boost::regex_iterator。
#include <iostream>
#include <string>
#include <algorithm>
#include <boost/regex.hpp>
const boost::regex expr{ R"__(\s*([a-zA-Z]+)\s*"(.*?)")__" };
const std::string s =
R"(VALUE "foo"
ANOTHERVALUE "bar"
YETANOTHERVALUE "barbar"
)";
int main() {
boost::sregex_iterator it{ begin(s), end(s), expr }, itEnd;
std::for_each( it, itEnd, []( const boost::smatch& m ){
std::cout << m[1] << '\n' << m[2] << std::endl;
});
}
注意:
答案 1 :(得分:1)
我会在这里使用一个小灵魂解析器:
<强> Live On Coliru 强>
#include <boost/fusion/adapted/std_pair.hpp> // reading maps
#include <boost/spirit/home/x3.hpp>
#include <boost/spirit/include/support_istream_iterator.hpp>
#include <iostream>
#include <fstream>
#include <map>
auto read_config_map(std::istream& stream) {
std::map<std::string, std::string> settings;
boost::spirit::istream_iterator f(stream >> std::noskipws), l;
using namespace boost::spirit::x3;
auto key_ = lexeme [ +upper ];
auto value_ = lexeme [ '"' >> *~char_('"') >> '"' ];
if (!phrase_parse(f, l, -(key_ >> value_) % eol >> eoi, blank, settings))
throw std::invalid_argument("cannot parse config map");
return settings;
}
auto read_config_map(std::string const& fname) {
std::ifstream stream(fname);
return read_config_map(stream);
}
int main() {
for (auto&& entry : read_config_map(std::cin))
std::cout << "Key:'" << entry.first << "' Value:'" << entry.second << "'\n";
}
打印:
Key:'ANOTHERVALUE' Value:'bar'
Key:'VALUE' Value:'foo'
Key:'YETANOTHERVALUE' Value:'barbar'