【问题标题】:c++ 11 regex error [duplicate]c ++ 11正则表达式错误[重复]
【发布时间】:2013-01-24 10:58:13
【问题描述】:

只是来自C++ Primer 5th Edition: 17.3.3. Using the Regular Expression Library的示例代码

主文件main.cpp:

#include <iostream>
#include "regexcase.h"
using namespace std;

int main() {
    using_regex();
    return 0;
}

头文件regexcase.h:

#ifndef REGEXCASE_H_
#define REGEXCASE_H_

#include <regex>
#include <string>

void using_regex();
std::string parseCode(std::regex_constants::error_type etype);

#endif /* REGEXCASE_H_ */

源文件regexcase.cpp:

#include "regexcase.h"
#include <iostream>
using namespace std;

void using_regex() {
    // look for words that violate a well-known spelling rule of thumb, "i before e, except after c":
    // find the characters ei that follow a character other than c
    string pattern("[^c]ei");
    // we want the whole word in which our pattern appears
    pattern = "[a-zA-Z]*" + pattern + "[a-zA-Z]*";  //[a-zA-Z]*   [[:alpha:]]*
    try {
        regex r(pattern, regex_constants::extended);    // construct a regex to find pattern                // , regex_constants::extended
        smatch results;     // define an object to hold the results of a search
        // define a string that has text that does and doesn't match pattern
        string test_str = "receipt freind theif receive";
        // use r to find a match to pattern in test_str
        if (regex_search(test_str, results, r)) // if there is a match
            cout << results.str() << endl;      // print the matching word
        else
            cout << "no match for " << pattern << endl;
    } catch (regex_error &e) {
        cout << "what: " << e.what() << "; code: " << parseCode(e.code()) << endl;
    }
}

string parseCode(regex_constants::error_type etype) {
    switch (etype) {
    case regex_constants::error_collate:
        return "error_collate: invalid collating element request";
    case regex_constants::error_ctype:
        return "error_ctype: invalid character class";
    case regex_constants::error_escape:
        return "error_escape: invalid escape character or trailing escape";
    case regex_constants::error_backref:
        return "error_backref: invalid back reference";
    case regex_constants::error_brack:
        return "error_brack: mismatched bracket([ or ])";
    case regex_constants::error_paren:
        return "error_paren: mismatched parentheses(( or ))";
    case regex_constants::error_brace:
        return "error_brace: mismatched brace({ or })";
    case regex_constants::error_badbrace:
        return "error_badbrace: invalid range inside a { }";
    case regex_constants::error_range:
        return "erro_range: invalid character range(e.g., [z-a])";
    case regex_constants::error_space:
        return "error_space: insufficient memory to handle this regular expression";
    case regex_constants::error_badrepeat:
        return "error_badrepeat: a repetition character (*, ?, +, or {) was not preceded by a valid regular expression";
    case regex_constants::error_complexity:
        return "error_complexity: the requested match is too complex";
    case regex_constants::error_stack:
        return "error_stack: insufficient memory to evaluate a match";
    default:
        return "";
    }
}

调用using_regex();的输出是what: regex_error; code: error_brack: mismatched bracket([ or ])

似乎正则表达式无法解析括号。

参考this question中的答案,我用regex_constants::extended来初始化正则表达式对象,那就是regex r(pattern, regex_constants::extended);

那么输出就是no match for [[:alpha:]]*[^c]ei[[:alpha:]]*

似乎正则表达式无法匹配模式。

然后我使用[a-zA-Z]* 替换字符类[[:alpha:]]*regex_constants::extended 仍然设置)。输出仍然是no match for [a-zA-Z]*[^c]ei[a-zA-Z]*

平台:windows

使用的工具:Eclipse for C/C++MinGW (g++ --version: g++ 4.7.2)

编辑: 感谢@sharth,添加主文件以完成代码。

【问题讨论】:

  • 很难调试正则表达式而不知道你给它什么输入。否则,恒星问题。
  • 它隐藏在那里,为test_str
  • 在 gcc-4.7 中 std::tr1::regex 不完整/功能不完整。请改用boost::regex
  • 我在使用 时遇到了类似的问题。原来我的 gcc (4.6) 不支持完整的正则表达式。然后我使用了 boost::regex,一切顺利。 (我已经在使用 boost)。

标签: c++ regex gcc c++11 libstdc++


【解决方案1】:

我刚刚使用 libc++ 和 clang++ 做了一个测试。这按预期工作。这是我的主要内容:

int main() {
    string test_str = "receipt freind theif receive";
    string pattern = "[a-zA-Z]*[^c]ei[a-zA-Z]*";

    try {
        regex r(pattern, regex_constants::extended);
        smatch results;

        if (regex_search(test_str, results, r))
            cout << results.str() << endl;
        else
            cout << "no match for " << pattern << endl;
    } catch (regex_error &e) {
        cout << "what: " << e.what() << "; code: " << parseCode(e.code()) << endl;
    }
}

输出:

freind

另一方面,GCC 4.7.2 给出了这个结果:

no match for [a-zA-Z]*[^c]ei[a-zA-Z]*

这是因为在 GCC 4.7.2 的 libstdc++ 中,它们仍然没有实现正则表达式。下面是regex_search的实现:

template<typename _Bi_iter, typename _Allocator, typename _Ch_type, typename _Rx_traits>
inline bool regex_search(_Bi_iter __first, _Bi_iter __last, match_results<_Bi_iter, _Allocator>& __m, const basic_regex<_Ch_type, _Rx_traits>& __re, regex_constants::match_flag_type __flags) {
    return false;
}

请注意,包含一个读者可以编译的小程序非常有帮助。这样就不会混淆正在运行的代码。

【讨论】:

  • 那我该怎么办?改用boost::regex,可以吗? (正如@Maxim Yegorushkin 上面所说)
  • Boost 的实现可以正常工作。事实上,我只是使用 Boost 的 1.53.0 和 GCC 4.7.2 做了一个快速测试,它的工作原理与 libc++ 相同。
  • clang 是什么版本?以上不适用于 3.3 rc2。
  • @wvxvw:当时我可能使用的是 OS X 附带的任何版本的 clang。然而,更大的问题是 libstdc++ 不包括对regex 的支持。因此,在 OS X 上,您可以使用 -stdlib=libc++ -std=c++11。在 Linux 上,您可能需要使用 boost 的实现。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-17
  • 2013-10-05
  • 1970-01-01
  • 2011-04-10
  • 1970-01-01
  • 2011-11-27
相关资源
最近更新 更多