我在 c++ 中使用 ECMA 脚本语法进行输入验证,并且在更改编译器时遇到了问题。使用交替时,应使用左起第一个匹配的表达式,除非被正则表达式的其余部分取消资格。因此,对于字符串"abcde"
,表达式"ab?|ab?(?:cd|dc)"
应该匹配"ab"
。我发现不同的编译器对此有不同的看法。
MCVE:
#include <regex>
#include <string>
#include <iostream>
int main()
{
std::string line = "abcde";
{
const std::string RX_ION_TYPE("ab?|ab?(?:cd|dc)");
const auto regexType = std::regex::ECMAScript;
std::regex rx_ionType;
rx_ionType.assign(
"(" + RX_ION_TYPE + ")"
, regexType);
std::smatch match;
if (std::regex_search(line, match, rx_ionType))
{
for (int i = 0; i < match.size(); i++)
{
std::cout << "|" << match.str(i) << "|\n";
}
}
else
{
std::cout << "No match.\n";
}
}
{
const std::string RX_ION_TYPE("ab?(?:cd|dc)|ab?");
const auto regexType = std::regex::ECMAScript;
std::regex rx_ionType;
rx_ionType.assign(
"(" + RX_ION_TYPE + ")"
, regexType);
std::smatch match;
if (std::regex_search(line, match, rx_ionType))
{
for (int i = 0; i < match.size(); i++)
{
std::cout << "|" << match.str(i) << "|\n";
}
}
else
{
std::cout << "No match.\n";
}
}
{
const std::string RX_ION_TYPE("ab?(?:cd|dc)?");
const auto regexType = std::regex::ECMAScript;
std::regex rx_ionType;
rx_ionType.assign(
"(" + RX_ION_TYPE + ")"
, regexType);
std::smatch match;
if (std::regex_search(line, match, rx_ionType))
{
for (int i = 0; i < match.size(); i++)
{
std::cout << "|" << match.str(i) << "|\n";
}
}
else
{
std::cout << "No match.\n";
}
}
return 0;
}
在线:ideone (gcc 5.1) cpp.sh (gcc 4.9.2) rextester
我希望得到
|ab|
|ab|
|abcd|
|abcd|
|abcd|
|abcd|
Visual Studio 2013、gcc 5.1 ( ideone ) 和 clang ( rextester )确实是这种情况,但对于我得到的 gcc 4.9 (ubuntu local 和cpp.sh ) 则不然
|abcd|
对于他们三个。
我的问题:
- 就标准而言,我假设从左到右读取交替是不正确的吗?
- gcc 4.9 似乎在 gcc 5 中被破坏和修复。由于我在实际项目中使用 CUDA,我必须继续使用 gcc 4.9。有没有办法让 gcc 4.9 使用标准约定(除了重写正则表达式)?