在 C++ 中使用带有正则表达式的 G++ 和 Visual Studio 14 2015 编译器时会产生不同的结果



当我注意到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标准下是正确的。

相关内容

  • 没有找到相关文章

最新更新