我正在使用std::regex
,但必须有一些我做错了。我有这样的字符串:
127.27.18.4_2.125.2.365.24.2_10
我必须在“_”之前取第一个字段,它是一个ip,第二个是snmp OID,最后一个是轮询时间。这些是我的模式:
\\d+\\.\\d+\\.\\d+\\.\\d+_(\\d+\\.)(\\d+\\.*)+_\\d+
\\d+\\.\\d+\\.\\d+\\.\\d+
_(\\d+\\.)(\\d+\\.*)+_
对于最后一个,我只是从字符串末尾开始搜索一个数字。
这是我的代码:
string generalCast = "\\d+\\.\\d+\\.\\d+\\.\\d+_(\\d+\\.)(\\d+\\.*)+_\\d+";
string input = "";
string ip = "";
if (regex_match(input, regex(generalCast)))
{
string ipCast = "\\d+\\.\\d+\\.\\d+\\.\\d+";
string oidCast = "_(\\d+\\.)(\\d+\\.*)+_";
string oid = "";
string polling = "";
smatch matches;
if (regex_match(input, matches, regex(ipCast)))
{
ip = matches[0];
oid = "Error, bad OID: " + input;
if (regex_match(input, matches, regex(oidCast)))
{
oid = regex_replace((string)matches[0], regex("_"), "");
regex_match(input.cend(), input.cbegin(), matches, regex("\\d+"));
if (matches.length() > 0)
{
polling = matches[0];
}
}
}
}
案例是程序从第一个if开始,但在第二个我只询问ip时,它不匹配。 我习惯于使用.Net中的正则表达式和类似的工作。
我做错了什么?
我需要使用RE,因为我需要知道字段何时出错。在我使用之前:stringstream和getlines。
答案 0 :(得分:2)
如果您坚持使用代码,这里有一个固定的代码段:
string generalCast = R"(\d+\.\d+\.\d+\.\d+_(\d+\.)(\d+\.*)+_\d+)";
string input = "127.27.18.4_2.125.2.365.24.2_10";
string ip = "";
if (regex_match(input, regex(generalCast)))
{
string ipCast = R"(\d+\.\d+\.\d+\.\d+)";
string oidCast = R"(_(\d+\.)(\d+\.*)+_)";
string oid = "";
string polling = "";
std::cout << "string object matched\n";
smatch matches;
if (regex_search(input, matches, regex(ipCast)))
{
std::cout << "ipCast matched: " << matches[0] << "\n";
ip = matches[0];
oid = "Error, bad OID: " + input;
smatch matches1;
if (regex_search(input, matches1, regex(oidCast)))
{
std::cout << "oidCast matched\n";
oid = regex_replace((string)matches1[0], regex("_"), "");
std::cout << "oid: " << oid << "\n";
smatch matches2;
regex_search(input, matches2, regex(R"(\d+$)"));
if (matches2.length() > 0)
{
polling = matches2[0];
std::cout << "Polling: " << polling << "\n";
}
}
}
}
请参阅IDEONE demo
事情发生了变化:smatch
,您无法重复使用regex_match
(因为它需要完整的字符串匹配),然后,您需要使用regex_search
,因为它允许部分匹配\d+
正则表达式会为您提供第一个数字序列,而不是最后一个(因此,您需要\d+$
正则表达式。)R"(...)"
)更实用。如果你问我,我会使用以下内容(使用捕获机制):
string generalCast = R"((\d+(?:\.\d+){3})_(\d+(?:\.\d+)+)_(\d+))";
string input = "127.27.18.4_2.125.2.365.24.2_10";
std::regex rx(generalCast);
smatch m;
if (std::regex_match(input, m, rx)) {
std::cout << m[1].str() <<"\n";
std::cout << m[2].str() <<"\n";
std::cout << m[3].str() <<"\n";
}
结果:
127.27.18.4
2.125.2.365.24.2
10
正则表达式(应与整个字符串匹配)表示:
(\d+(?:\.\d+){3})
- 一个或多个数字,后跟3次.
+ 1位或更多位数_
- 文字_
(\d+(?:\.\d+)+)
- 一个或多个数字后跟一个或多个.
+ 1个或更多个数字_
- 文字_
(\d+)
- 最后一位或多位数字