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

C++中如何用正则表达式捕获Python运算符与分隔符?

Python JIT编译器分词阶段:正则匹配多字符符号与特殊分隔符解决方案

核心思路

要实现保留分隔符的分词,正则必须优先匹配多字符符号(比如-=、//、!=),再处理单字符的运算符/分隔符,同时对正则里有特殊含义的字符([、]、(、)等)做转义,避免匹配逻辑出错。

正确的正则表达式

把所有多字符符号放在正则最前面,确保它们不会被拆成单字符匹配。以下是覆盖Python常见运算符和分隔符的正则:

(-=|\+=|\/=|\*=|==|!=|<=|>=|\/\/|\*\*|\(|\)|\[|\]|,|;|\.|\+|-|\/|\*|=|<|>|!)

正则说明

  • 多字符符号组:-=、+=、/=、*=、==、!=、<=、>=、//、**(Python中的复合运算符)
  • 转义的特殊字符:(、)、[、](正则元字符,必须用\转义才能匹配本身)
  • 普通单字符:,、;、.、+、-、/、*、=、<、>、!

修改后的C++实现代码

原代码存在两个问题:一是C++的std::string没有substring方法(应使用substr),二是手动修改line会导致正则迭代器失效。改用std::sregex_token_iterator可以更简洁安全地实现需求:

/// @brief 将代码行拆分为词法单元列表,同时保留分隔符本身
/// @param line 待分词的代码行引用
/// @return 可供解析的词法单元列表
std::list<std::string> breakDown(std::string& line) {
    std::list<std::string> lexemes;
    // 用原始字符串字面量避免双重转义,优先匹配多字符符号
    std::regex delimiters(R"((-=|\+=|\/=|\*=|==|!=|<=|>=|\/\/|\*\*|\(|\)|\[|\]|,|;|\.|\+|-|\/|\*|=|<|>|!))");
    
    // -1 匹配分隔符以外的内容,0 匹配分隔符本身,一次性获取所有token
    std::sregex_token_iterator it(line.begin(), line.end(), delimiters, {-1, 0});
    std::sregex_token_iterator end;
    
    for (; it != end; ++it) {
        std::string token = *it;
        // 跳过空字符串,比如连续分隔符之间的空白内容
        if (!token.empty()) {
            lexemes.push_back(token);
        }
    }
    
    return lexemes;
}

关键改进点

  1. 原始字符串字面量:用R"(...)"包裹正则,不用写双重转义的\\,代码更易读。
  2. sregex_token_iterator的正确用法:通过{-1, 0}参数,自动把分隔符和非分隔符内容都提取出来,不需要手动截取字符串,彻底避免迭代器失效问题。
  3. 空token过滤:处理类似a+++b这种连续运算符的场景,不会把中间的空字符串加入词法单元列表。

测试效果示例

输入代码行:x += 5 // 2; y != [1,2]
分词后的结果为:
"x", " += ", "5", " // ", "2", ";", " y", " != ", "[", "1", ",", "2", "]"

内容的提问来源于stack exchange,提问作者Владислав Король

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 03:35:26