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

C++正则表达式匹配问题:提取含共享字母的重叠数字单词

解决C++正则提取重叠数字单词的问题

你需要处理像"twone"(需提取"two"和"one")、"eightwo"(需提取"eight"和"two")这类包含重叠数字单词的字符串,但普通正则匹配会因字符消耗只能捕获其中一个。以下是具体解决方案:

核心思路

  • 普通正则匹配会消耗已匹配的字符,导致重叠部分无法被二次匹配。
  • 使用正向预查(positive lookahead):预查不会消耗字符串字符,允许在同一位置检查是否存在匹配的单词。
  • 遍历字符串每个位置,逐个检查匹配,确保不遗漏重叠项。

修改后的代码

#include <iostream>
#include <string>
#include <regex>
#include <map>
#include <vector>

int main() {
    std::map<std::string, std::string> wordToDigit = {
        {"zero", "0"}, {"one", "1"}, {"two", "2"}, {"three", "3"}, {"four", "4"},
        {"five", "5"}, {"six", "6"}, {"seven", "7"}, {"eight", "8"}, {"nine", "9"}
    };
    std::string inputString = "eightwo"; // 可替换为"twone"、"nineight"等测试用例
    // 正向预查捕获数字单词,不消耗字符
    std::regex pattern(R"(?=(zero|one|two|three|four|five|six|seven|eight|nine))");
    std::smatch match;
    std::vector<std::string> allDigits;

    size_t pos = 0;
    // 循环搜索,每次移动一个字符,确保不遗漏重叠匹配
    while (pos < inputString.size() && std::regex_search(inputString.begin() + pos, inputString.end(), match, pattern)) {
        if (!match[1].str().empty()) {
            allDigits.push_back(match[1].str());
        }
        pos += 1; // 移动1个字符而非匹配长度,允许重叠匹配
    }

    if (!allDigits.empty()) {
        std::vector<std::string> allNumericDigits;
        for (const std::string& digit : allDigits) {
            auto mapIt = wordToDigit.find(digit);
            if (mapIt != wordToDigit.end()) {
                allNumericDigits.push_back(mapIt->second);
            } else {
                // 若需处理数字字符,可在此补充逻辑
                allNumericDigits.push_back(digit);
            }
        }

        std::string firstDigit = allNumericDigits.front();
        std::string lastDigit = allNumericDigits.back();
        std::string concatenatedNumberStr = firstDigit + lastDigit;
        int concatenatedNumber = std::stoi(concatenatedNumberStr);

        std::cout << concatenatedNumber << std::endl;
        return concatenatedNumber;
    }
    return 0;
}

关键部分解释

  • 正则模式:(?=(...)) 是正向预查结构,仅检查当前位置后是否存在目标单词,不消耗字符;括号内的捕获组用于提取匹配到的单词。
  • 循环逻辑:每次匹配后将搜索起始位置pos加1,而非跳到匹配结束位置。例如"twone"中,位置0匹配"two",位置3匹配"one",确保重叠项被捕获。
  • Map查找优化:改用find方法替代直接下标访问,避免键不存在时自动插入空值的问题,提升安全性。

测试结果

  • 输入"twone":allDigits得到["two", "one"],最终输出21
  • 输入"eightwo":allDigits得到["eight", "two"],最终输出82
  • 输入"nineight":allDigits得到["nine", "eight"],最终输出98

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 22:50:38