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]*)\""存在两个核心问题:
[^\"]*会匹配到第一个未转义的双引号就停止,无法识别内部的转义双引号(\"),导致内容被截断- 未处理转义字符逻辑,遇到
\"时直接中断匹配,丢失后续有效内容
正确的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; }
代码说明
- 原始字符串字面量:使用
R"(...)"避免C++字符串中转义字符的多层处理,让正则表达式更易读 - 正则逻辑:
(?:[^"\\]|\\(?!\\)")*:非捕获组,匹配两种情况:要么是非引号、非反斜杠的字符,要么是转义双引号(\")(?!\\)":确保引号未被转义std::regex_constants::dotall:让.匹配换行符,和Python的re.DOTALL一致
- 遍历方式:使用
std::sregex_iterator替代regex_search循环,更简洁高效
验证结果
将输入文本代入上述代码后,输出与预期完全一致,正确保留了转义双引号对应的内容。
内容的提问来源于stack exchange,提问作者Ankan Roy
相关产品推荐
相关产品推荐

