You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MSVC2015(C++11)下用std::regex_match匹配自定义字符类的问题

问题分析与解决方案

编译错误的核心原因:

  • 你使用的std::regex是std::basic_regex<char>的别名,与迭代器指向的MyChar类型字符不匹配;
  • 即使换成std::basic_regex<char32_t>,标准库正则函数也无法直接处理MyChar迭代器,因为其value_type不是char32_t。

以下是两种无需转换为std::u32string的实现方案:


方案一:迭代器适配器(零拷贝,推荐)

实现轻量级迭代器适配器,将MyChar迭代器包装为指向char32_t的迭代器,全程无内存分配与拷贝:

#include <regex>
#include <iterator>
#include <vector>

struct MyChar {
    char32_t c;
    int color_id;
    
    MyChar(char32_t wc) : c(wc), color_id(1) {}
    operator char32_t()const { return c; }

    MyChar() : c(0), color_id(1) {}
    MyChar(const MyChar&) = default;
    MyChar& operator=(const MyChar& cc) { 
        c = cc.c; 
        color_id = cc.color_id; 
        return *this; 
    }
    bool operator==(const MyChar& c2)const { return c == c2.c; }
    bool operator!=(const MyChar& c2)const { return c != c2.c; }
};

// 迭代器适配器:将MyChar迭代器转换为char32_t迭代器
template <typename Iter>
struct MyCharToChar32Iter : public std::iterator<std::bidirectional_iterator_tag, const char32_t> {
    Iter base;

    MyCharToChar32Iter(Iter it) : base(it) {}

    const char32_t& operator*() const { return base->c; }
    const char32_t* operator->() const { return &base->c; }

    MyCharToChar32Iter& operator++() { ++base; return *this; }
    MyCharToChar32Iter operator++(int) { auto tmp = *this; ++base; return tmp; }

    MyCharToChar32Iter& operator--() { --base; return *this; }
    MyCharToChar32Iter operator--(int) { auto tmp = *this; --base; return tmp; }

    bool operator==(const MyCharToChar32Iter& other) const { return base == other.base; }
    bool operator!=(const MyCharToChar32Iter& other) const { return base != other.base; }
};

int main(int, char**) {
    std::vector<MyChar> line = {U'H', U'e', U'l', U'l', U'o', U' ', U'W', U'o', U'r', U'l', U'd'};
    // 使用char32_t版本的正则表达式,模式串用U""前缀声明
    std::basic_regex<char32_t> rx(U"\\b(hello|world)\\b", std::regex::icase);

    // 包装原迭代器
    auto first = MyCharToChar32Iter<decltype(line.begin())>(line.begin());
    auto last = MyCharToChar32Iter<decltype(line.end())>(line.end());

    // match_results的迭代器类型需与适配后的迭代器一致
    std::match_results<decltype(first)> matches;
    if (std::regex_match(first, last, rx, matches)) {
        // 如需获取原MyChar序列的匹配范围,通过base()方法反向获取原迭代器
        auto start_iter = matches[0].first.base();
        auto end_iter = matches[0].second.base();
    }
}

关键说明:

  • 适配器仅包装原迭代器,解引用时直接返回MyChar的c成员,无额外开销;
  • 若需操作原MyChar对象,可通过match_results中迭代器的base()方法获取原vector的迭代器;
  • 正则表达式必须使用std::basic_regex<char32_t>,模式串需对应char32_t类型。

方案二:特化std::char_traits<MyChar>(需谨慎)

通过特化标准库的char_traits模板,让正则函数直接识别MyChar作为字符类型。注意:特化标准库模板需严格遵循标准要求,且MSVC2015可能存在兼容性限制:

#include <regex>
#include <vector>
#include <cstring>
#include <cwchar>

struct MyChar {
    char32_t c;
    int color_id;
    
    MyChar(char32_t wc) : c(wc), color_id(1) {}
    operator char32_t()const { return c; }

    MyChar() : c(0), color_id(1) {}
    MyChar(const MyChar&) = default;
    MyChar& operator=(const MyChar& cc) { 
        c = cc.c; 
        color_id = cc.color_id; 
        return *this; 
    }
    bool operator==(const MyChar& c2)const { return c == c2.c; }
    bool operator!=(const MyChar& c2)const { return c != c2.c; }
};

// 特化char_traits<MyChar>,实现标准要求的所有静态方法
namespace std {
    template<>
    struct char_traits<MyChar> {
        using char_type = MyChar;
        using int_type = int;
        using off_type = streamoff;
        using pos_type = streampos;
        using state_type = mbstate_t;

        static void assign(char_type& a, const char_type& b) { a = b; }
        static bool eq(const char_type& a, const char_type& b) { return a.c == b.c; }
        static bool lt(const char_type& a, const char_type& b) { return a.c < b.c; }

        static int compare(const char_type* s1, const char_type* s2, size_t n) {
            for (size_t i = 0; i < n; ++i) {
                if (s1[i].c != s2[i].c) {
                    return s1[i].c < s2[i].c ? -1 : 1;
                }
            }
            return 0;
        }

        static size_t length(const char_type* s) {
            size_t len = 0;
            while (s[len].c != 0) ++len;
            return len;
        }

        static const char_type* find(const char_type* s, size_t n, const char_type& a) {
            for (size_t i = 0; i < n; ++i) {
                if (s[i].c == a.c) return &s[i];
            }
            return nullptr;
        }

        static char_type* move(char_type* s1, const char_type* s2, size_t n) {
            return static_cast<char_type*>(memmove(s1, s2, n * sizeof(char_type)));
        }

        static char_type* copy(char_type* s1, const char_type* s2, size_t n) {
            return static_cast<char_type*>(memcpy(s1, s2, n * sizeof(char_type)));
        }

        static char_type* assign(char_type* s, size_t n, char_type a) {
            for (size_t i = 0; i < n; ++i) s[i] = a;
            return s;
        }

        static char_type to_char_type(const int_type& c) { return MyChar(static_cast<char32_t>(c)); }
        static int_type to_int_type(const char_type& c) { return static_cast<int>(c.c); }
        static bool eq_int_type(const int_type& c1, const int_type& c2) { return c1 == c2; }
        static int_type eof() { return static_cast<int_type>(U'\0'); }
        static int_type not_eof(const int_type& c) { return c != eof() ? c : 1; }
    };
}

int main(int, char**) {
    std::vector<MyChar> line = {U'H', U'e', U'l', U'l', U'o', U' ', U'W', U'o', U'r', U'l', U'd'};
    // 将u32string模式串转换为MyChar序列构造正则
    std::u32string pattern = U"\\b(hello|world)\\b";
    std::vector<MyChar> rx_pattern(pattern.begin(), pattern.end());
    std::basic_regex<MyChar> rx(rx_pattern.begin(), rx_pattern.end(), std::regex::icase);

    std::match_results<std::vector<MyChar>::const_iterator> matches;
    if (std::regex_match(line.begin(), line.end(), rx, matches)) {
        // 直接使用matches中的原MyChar迭代器
    }
}

关键说明:

  • 需实现char_traits要求的所有静态方法,代码量较大;
  • 构造正则时需将u32string模式串转换为MyChar序列,该转换开销极小且可提前完成;
  • 该方案在MSVC2015中需测试验证兼容性。

内容的提问来源于stack exchange,提问作者KungPhoo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 19:59:50