以下是我的代码的一部分
foo.bar = 15
baz.asd = 13
ddd.dgh = 66
我尝试将它从文件中读取的行分开 - 行看起来像:
a = foo
b = bar
c = 15
我想从中提取部分 - 例如对于第一行foo.bar = 15,我想最终得到类似的东西:
HashMap
但是现在,正则表达式总是假的,我在许多在线正则表达式检查器上测试过,甚至在visual studio中,它工作得很好,我是否需要一些不同的C ++ regex_match语法?我正在使用visual studio 2013社区
答案 0 :(得分:9)
问题是std::regex_match必须匹配整个字符串,但您只想匹配其中的一部分。
您需要使用std::regex_search或更改正则表达式以同时匹配所有三个部分:
#include <regex>
#include <string>
#include <iostream>
const auto test =
{
"foo.bar = 15"
, "baz.asd = 13"
, "ddd.dgh = 66"
};
int main()
{
const std::regex r(R"~(([^.]+)\.([^\s]+)[^0-9]+(\d+))~");
// ( 1 ) ( 2 ) ( 3 ) <- capture groups
std::cmatch m;
for(const auto& line: test)
{
if(std::regex_match(line, m, r))
{
// m.str(0) is the entire matched string
// m.str(1) is the 1st capture group
// etc...
std::cout << "a = " << m.str(1) << '\n';
std::cout << "b = " << m.str(2) << '\n';
std::cout << "c = " << m.str(3) << '\n';
std::cout << '\n';
}
}
}
正则表达式:https://regex101.com/r/kB2cX3/2
<强>输出:强>
a = foo
b = bar
c = 15
a = baz
b = asd
c = 13
a = ddd
b = dgh
c = 66
答案 1 :(得分:2)
要关注regex
模式,我更倾向于在c ++中使用raw string literals:
regex cvarPattern ( R"rgx(\.([a-zA-Z_]+))rgx" );
regex parentPattern ( R"rgx(^([a-zA-Z0-9_]+)\.)rgx" );
regex cvarValue ( R"rgx(\.[a-zA-Z0-9_]+[ ]*=[ ]*(\d+\.*\d*))rgx" );
rgx(
)rgx
分隔符之间的所有内容都不需要为c ++ char字面字符进行任何额外的转义。
实际上你在你的问题中所写的内容类似于那些我用原始字符串文字书写的正则表达式。
你可能只是意味着
regex cvarPattern ( R"rgx(.([a-zA-Z_]+))rgx" );
regex parentPattern ( R"rgx(^([a-zA-Z0-9_]+).)rgx" );
regex cvarValue ( R"rgx(.[a-zA-Z0-9_]+[ ]*=[ ]*(\d+(\.\d*)?))rgx" );
我没有深入挖掘,但我现在没有在你的正则表达式模式中获得所有这些转义字符。
关于评论中的问题,您可以选择匹配的子模式组,并检查匹配结构中应用了哪些子组:
regex cvarValue (
R"rgx(.[a-zA-Z0-9_]+[ ]*=[ ]*((\d+)|(\d+\.\d?)|([a-zA-Z]+)){1})rgx" );
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
您可能不需要这些cvarPattern
和parentPattern
正则表达式来检查有关匹配模式的其他(更详细)视图。