入力検証のために 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
私は得ることを期待します
|アブ|
|アブ|
|abcd|
|abcd|
|abcd|
|abcd|
これは、Visual Studio 2013、gcc 5.1 ( ideone )、および clang ( rextester ) には当てはまりますが、gcc 4.9 (ローカルの ubuntu およびcpp.sh ) には当てはまりません。
|abcd|
それらの3つすべてのために。
私の質問:
- 標準に関する限り、交代が左から右に読み取られるという私の仮定は間違っていますか?
- gcc 4.9 は壊れていて、gcc 5 で修正されているようです。実際のプロジェクトでは CUDA を使用しているため、gcc 4.9 を使い続ける必要があります。gcc 4.9 で標準規約を使用する方法はありますか (正規表現を書き換える以外に) ?