编译器之间的正则表达式交替顺序差异

时间:2016-07-21 12:19:07

标签: c++ regex gcc clang cl

我在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本地和cpp.sh)我得到的地方

  

| ABCD |

所有这三个人。

我的问题:

  1. 我的假设是,就标准而言,从左到右读取的交替是错误的吗?
  2. gcc 4.9似乎在gcc 5中被破解并修复。由于我在实际项目中使用CUDA,我必须继续使用gcc 4.9。有没有办法让gcc 4.9使用标准约定(除了重写正则表达式)?

0 个答案:

没有答案