当我注意到g++(MinGW(和Visual Studio 14 2015编译器(都在Windows上(之间有一些不规则性时,我正在用c ++玩正则表达式。这是我尝试过的代码:
#include <iostream>
#include <vector>
#include <string>
#include <regex>
static const std::string data = "n a = 10n b = 20n";
int main(int argc, char* argv[])
{
auto strIt = data.begin();
while (strIt != data.end())
{
std::regex e("^[ tnr]");
std::smatch m;
std::string s(strIt, data.end());
if (std::regex_search(s, m, e))
{
strIt += m[0].str().size();
}
else
{
std::cout << "s = "" << s << """ << 'n';
break;
}
}
}
使用 g++ 编译时,我得到的预期输出为
s = "a = 10n b = 20n"
但是当使用Visual Studio编译器时,它会吐出来
s = "b = 20n"
忽略整个"a = 10"部分。在通过调试功能在视觉工作室中进一步调查后,我看到 m 变量保留了"a = 10"部分之后的空间。
你知道它为什么会这样吗?我是否在某处犯了一个大错误而没有注意到它?请帮忙。
首先,一个简化的示例:
#include <iostream>
#include <string>
#include <regex>
using namespace std;
int main() {
const string data = "abcnXabc";
regex re("^X");
smatch match;
if (regex_search(data, match, re))
cout << "match: " << match.str() << endl;
else
cout << "no match" << endl;
return 0;
}
Visual Studio 2015 输出:
匹配:X
MinGW 7.1.0 输出:
无匹配
因此,差异归结为正则表达式中的^
是与行的开头匹配还是仅与字符串的开头匹配。在第 17 C++中,它由传递给regex
构造函数的regex::flag_type
参数确定。
31.5.1 位掩码类型 syntax_option_type:
类型 syntax_option_type 是实现定义的位掩码类型。设置其元素具有表 130 中列出的效果。类型syntax_option_type的有效值最多应具有语法元素ECMAScript,basic,extended,awk,grep,egrep,set之一。如果未设置语法元素,则默认语法为 ECMAScript。
<小时 />表130 — syntax_option_type效应
。
multiline — 如果选择了 ECMAScript 引擎,则指定 ^ 应匹配行的开头,$ 应匹配行的结尾。
为了使^
匹配行首,regex
对象需要像这样初始化:
regex re("^X", regex_constants::multiline);
总之,MinGW的行为在C++17标准下是正确的。