对分隔符具有特定约束的拆分字符串
Posted
技术标签:
【中文标题】对分隔符具有特定约束的拆分字符串【英文标题】:Split string with specific constraint on delimiter 【发布时间】:2016-09-26 13:41:07 【问题描述】:假设我们有一个字符串:"((0.2,0), (1.5,0)) A1 ABC p"
。我想把它分成这样的逻辑单元:
((0.2,0), (1.5,0))
A1
ABC
p
即用空格分割字符串,要求前一个字符不是逗号。
是否可以使用regex
作为解决方案?
更新:我试过这样:
#include <iostream>
#include <string>
#include <regex>
int main()
std::string s = "((0.2,0), (1.5,0)) A1 ABC p";
std::regex re("[^, ]*\\(, *[^, ]*\\)*"); // as suggested in the updated answers
std::sregex_token_iterator
p(s.begin(), s.end(), re, -1);
std::sregex_token_iterator end;
while (p != end)
std::cout << *p++ << std::endl;
结果是:((0.2,0), (1.5,0)) A1 ABC p
解决方案:
#include <iostream>
#include <string>
#include <regex>
int main()
std::string s = "((0.2,0), (1.5,0)) A1 ABC p";
std::regex re("[^, ]*(, *[^, ]*)*");
std::regex_token_iterator<std::string::iterator> p(s.begin(), s.end(), re);
std::regex_token_iterator<std::string::iterator> end;
while (p != end)
std::cout << *p++ << std::endl;
输出:
((0.2,0), (1.5,0))
A1
ABC
p
【问题讨论】:
@TobySpeight,感谢您的纠正。我刚刚通过输入代码 sn-p 更新了问题。 这还不完整(一方面它缺少main()
),但它越来越接近了。当你有可以编译的东西时,请更新。
【参考方案1】:
你可以这样做:
[^, ]*(, *[^, ]*)*
这是做什么的?
首先让我们回顾一下正则表达式的基础知识:
[] 定义了您要匹配的一组字符,例如 [ab] 将匹配 'a' 或 'b'。
如果您使用 [^] 语法来描述您不想匹配的所有字符,那么 [^ab] 将匹配任何不是“a”或“b”的字符。
* 符号告诉正则表达式前一个匹配可以出现零次或多次。所以 a* 将匹配空字符串 '' or 'a' or 'aaa' or 'aaaaaaaaaaaaa'
当您将 () 放在创建组的表达式的一部分周围时,您可以在我们的例子中使用它来定义我们希望成为可选的模式的一部分* 在它旁边,以便它可以出现零次或多次。
好的,放在一起:
第一部分 [^ ,]* 表示:匹配零个或多个不是 ' ' 或 ' 的字符,这将匹配像 'A1' 或 '((0.2" ) 这样的字符串
()* 中的第二部分用于继续匹配包含 ',' 和空格但您不想拆分的字符串,这部分是可选的,以便正确匹配 'A1' 或 'ABC'或“p”。
所以 (, *[^, ]*)* 将匹配零个或多个以 ',' 开头的字符串以及任意数量的 ' ' 后跟一个不包含 ',' 或 ' ' 的字符串。因此,在您的示例中,它将匹配“,0)”,这是“((0.2”)的延续,也匹配“,(1.5”和“,0))”,它们将全部相加以形成“((0.2 ,0), (1.5,0))"
注意:您可能需要根据您使用的正则表达式库对表达式中的某些字符进行转义。该解决方案将在此在线测试器中运行http://www.regexpal.com/
但有些库和工具需要你逃避诸如 (
所以表达式看起来像:
[^, ]*\(, *[^, ]*\)*
我还删除了 (|$) 部分,仅当您希望结尾空格成为匹配的一部分时才需要它。
【讨论】:
以上是关于对分隔符具有特定约束的拆分字符串的主要内容,如果未能解决你的问题,请参考以下文章