我有一个文本文件,目前正在使用正则表达式解析,并且它工作得很好。文件格式已经定义好了,是两个数字,中间用任何空格隔开,后面可以跟一个可选的注释。
现在,我们需要向这个文件添加一个额外的(但可选的)第三个数字,使格式为2或3个数字用空格隔开并带有注释的情况。
我有一个正则表达式对象,至少匹配所有必要的行格式,但如果存在第三个(可选的)数字,我无法捕获它。
代码:
这将产生以下输出:
现在,我们需要向这个文件添加一个额外的(但可选的)第三个数字,使格式为2或3个数字用空格隔开并带有注释的情况。
我有一个正则表达式对象,至少匹配所有必要的行格式,但如果存在第三个(可选的)数字,我无法捕获它。
代码:
#include <iostream>
#include <regex>
#include <vector>
#include <string>
#include <cassert>
using namespace std;
bool regex_check(const std::string& in)
{
std::regex check{
"[[:space:]]*?" // eat leading spaces
"([[:digit:]]+)" // capture 1st number
"[[:space:]]*?" // each second set of spaces
"([[:digit:]]+)" // capture 2nd number
"[[:space:]]*?" // eat more spaces
"([[:digit:]]+|[[:space:]]*?)" // optionally, capture 3rd number
"!*?" // Anything after '!' is a comment
".*?" // eat rest of line
};
std::smatch match;
bool result = std::regex_match(in, match, check);
for(auto m : match)
{
std::cout << " [" << m << "]\n";
}
return result;
}
int main()
{
std::vector<std::string> to_check{
" 12 3",
" 1 2 ",
" 12 3 !comment",
" 1 2 !comment ",
"\t1\t1",
"\t 1\t 1\t !comment \t",
" 16653 2 1",
" 16654 2 1 ",
" 16654 2 1 ! comment",
"\t16654\t\t2\t 1\t ! comment\t\t",
};
for(auto s : to_check)
{
assert(regex_check(s));
}
return 0;
}
这将产生以下输出:
[ 12 3]
[12]
[3]
[]
[ 1 2 ]
[1]
[2]
[]
[ 12 3 !comment]
[12]
[3]
[]
[ 1 2 !comment ]
[1]
[2]
[]
[ 1 1]
[1]
[1]
[]
[ 1 1 !comment ]
[1]
[1]
[]
[ 16653 2 1]
[16653]
[2]
[]
[ 16654 2 1 ]
[16654]
[2]
[]
[ 16654 2 1 ! comment]
[16654]
[2]
[]
[ 16654 2 1 ! comment ]
[16654]
[2]
[]
正如您所看到的,这段代码可以匹配所有期望的输入格式,但却无法捕获第三个数字,即使它存在。
我目前正在使用GCC 5.1.1进行测试,但实际目标编译器将是GCC 4.8.2,使用boost :: regex
代替std :: regex
。
\s*(\d+)\s+(\d+)(?:\s+(\d+))?\s*(?:!.*)?
,我会睡得更好。非贪婪量词让我感到紧张。 - melpomene