寻求匹配引号、方括号、花括号外空格的正则表达式(适配Boost::Regex)
正则分词需求:排除引号、方括号、花括号内的空格
需求概述
需要实现字符串分词逻辑:
- 分割符为不在双引号、方括号
[]、花括号{}内的空格,同时支持按,或;分割 - 正则需可在正则测试工具中验证,目标分割空格需能被高亮
- 基于C++ Boost::Regex库实现
示例
输入
" Test Test " ab c " Test" "Test " "Test" "T e s t"
期望输出
[" Test Test ",ab,c," Test","Test ","Test","T e s t"]
现有代码及问题
当前实现中,用于忽略引号内空格的正则逻辑失效,代码如下:
... std::string test_string("\" Test Test \" ab c \" Test\" \"Test \" \"Test\" \"T e s t\""); // (,|;)?\\s+ : Split on ,\s or ;\s // (?![^\\[]*\\]) : Ignore spaces inside [] // (?![^\\{]*\\}) : Ignore spaces inside {} // (?![^\"].*\") : Ignore spaces inside "" !!! 此逻辑无法正常工作 !!! // 注:以下分隔符正则未包含上述错误的引号处理逻辑 boost::regex delimiter("(,|;\\s|\\s)+(?![^\\[]*\\])(?![^\\(]*\\))(?![^\\{]*\\})"); std::vector<std::string> string_vector; boost::split_regex(string_vector, test_string, delimiter);
原引号处理前瞻(?![^\"].*\")的问题:未考虑引号内的转义字符\",且匹配逻辑无法正确识别成对的未转义引号,导致无法准确排除引号内的空格。
修正方案
适配Boost的正则分隔符
(?:,|;)?\s+(?![^\[]*\])(?![^\{]*\})(?![^"\\]*(?:\\.[^"\\]*)*")
正则逻辑解释
(?:,|;)?\s+:匹配可选的,或;后跟1个及以上空格,作为有效分割符(?![^\[]*\]):正向否定前瞻,确保当前空格不在未闭合的方括号内(?![^\{]*\}):正向否定前瞻,确保当前空格不在未闭合的花括号内(?![^"\\]*(?:\\.[^"\\]*)*"):正向否定前瞻,检查当前位置后是否存在未转义的闭合引号——若存在,说明空格在引号内,跳过不分割。该逻辑支持引号内的转义字符(如\")。
修改后的代码
使用Boost支持的原始字符串字面量简化转义:
... std::string test_string("\" Test Test \" ab c \" Test\" \"Test \" \"Test\" \"T e s t\""); boost::regex delimiter(R"(?:,|;)?\s+(?![^\[]*\])(?![^\{]*\})(?![^"\\]*(?:\\.[^"\\]*)*")"); std::vector<std::string> string_vector; boost::split_regex(string_vector, test_string, delimiter);
验证说明
该正则可在正则测试工具中正确高亮所有待分割的空格,Boost::Regex执行后可得到符合预期的分词结果,同时支持转义引号的场景。
内容的提问来源于stack exchange,提问作者Warren Niles
相关产品推荐
相关产品推荐

