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

Python正则提取文本逻辑转C++结果异常,求正确实现方案

正确提取带转义双引号的C++正则实现

问题背景

原Python代码可正确提取被双引号包裹、内部包含转义双引号的文本,但自行实现的C++代码提取结果错误,丢失了转义双引号对应的内容。

原Python代码

def extractText(self):
    text = self.datum_buffer
    if re.match(r'[ \t\r\n]*"', text, flags=re.DOTALL):
        lines = []
        for m in re.finditer(r'[ \t]*(?!\\)"(?P<text>([^"\\]|\\(?!\\)")*)(?!\\)"[ \t]*\r?\n?', text, flags=re.DOTALL):
            lines.append(m.group('text'))
        text = ''.join(lines)
    return text

输入文本

"------${session.boundary}\r\nContent-Type: image/jpeg\r\nContent-Disposition: form-data; name=\"image_name\"; filename=\"${command.uploaded_filename}\"\r\n\r\n${command.image_raw_bytes}\r\n------${session.boundary}--"

预期输出

------${session.boundary}
Content-Type: image/jpeg
Content-Disposition: form-data; name="image_name"; filename="${command.uploaded_filename}"

${command.image_raw_bytes}
------${session.boundary}--

错误的C++代码

std::string extractText() {
    std::string result = this->datum_buffer;
    std::string extractedText = "";
    // Check if text starts with optional whitespace followed by a double quote
    if (std::regex_search(result, std::regex("[ \t\r\n]*\""))) {
        std::regex pattern("\"([^\"]*[\r\n]*)\"");
        std::smatch matches;

        while (std::regex_search(result, matches, pattern)) {
            std::string match = matches[1];
                    
            extractedText += match;
            result = matches.suffix().str();
        }
     }
            
     if (extractedText.empty())
         extractedText = result;
     return extractedText;
}

当前错误输出

------${session.boundary}
Content-Type: image/jpeg
Content-Disposition: form-data; name=; filename=\

${command.image_raw_bytes}
------${session.boundary}--

错误原因分析

当前C++正则"\"([^\"]*[\r\n]*)\""存在两个核心问题:

  1. [^\"]*会匹配到第一个未转义的双引号就停止,无法识别内部的转义双引号(\"),导致内容被截断
  2. 未处理转义字符逻辑,遇到\"时直接中断匹配,丢失后续有效内容

正确的C++实现

对齐原Python的正则逻辑,在C++中需注意字符串转义(正则中的\需写成\\,双引号写成\"),同时启用dotall模式让.匹配换行符:

#include <regex>
#include <string>
#include <iterator>

std::string extractText() {
    std::string text = this->datum_buffer;
    std::string extractedText;

    // 匹配开头的空白+引号,和原Python逻辑一致
    std::smatch startMatch;
    if (std::regex_search(text, startMatch, std::regex(R"([ \t\r\n]*)")) && 
        startMatch.suffix().str().size() > 0 && 
        startMatch.suffix().str()[0] == '"') {

        // 核心正则:匹配带转义双引号的内容,和原Python正则逻辑对齐
        // R"(...)" 是C++原始字符串,避免多层转义
        std::regex contentPattern(R"([ \t]*(?!\\)"((?:[^"\\]|\\(?!\\)")*)(?!\\)"[ \t]*\r?\n?)", 
                                 std::regex_constants::dotall);

        // 使用sregex_iterator遍历所有匹配项
        std::sregex_iterator it(text.begin(), text.end(), contentPattern);
        std::sregex_iterator end;

        for (; it != end; ++it) {
            extractedText += (*it)[1].str();
        }
    }

    // 若未提取到内容,返回原文本
    return extractedText.empty() ? text : extractedText;
}

代码说明

  1. 原始字符串字面量:使用R"(...)"避免C++字符串中转义字符的多层处理,让正则表达式更易读
  2. 正则逻辑:
    • (?:[^"\\]|\\(?!\\)")*:非捕获组,匹配两种情况:要么是非引号、非反斜杠的字符,要么是转义双引号(\")
    • (?!\\)":确保引号未被转义
    • std::regex_constants::dotall:让.匹配换行符,和Python的re.DOTALL一致
  3. 遍历方式:使用std::sregex_iterator替代regex_search循环,更简洁高效

验证结果

将输入文本代入上述代码后,输出与预期完全一致,正确保留了转义双引号对应的内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 11:21:26