拆分分隔符上具有特定约束的字符串

时间:2016-09-26 13:41:07

标签: c++ regex string split

假设我们有一个字符串:"((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

1 个答案:

答案 0 :(得分:1)

你可以这样做:

 [^, ]*(, *[^, ]*)*

这是做什么的?

首先介绍正则表达式的基础知识:

[]定义了一组你要匹配的字符,例如[ab]将匹配'a'或'b'。

如果您使用[^]语法描述您不想匹配的所有字符,那么[^ ab]将匹配NOT和'a'或'b'的任何内容。

*符号告诉正则表达式前一个匹配可以出现零次或多次。所以a *将匹配空字符串''或'a'或'aaa'或'aaaaaaaaaaaaa'

当你把()放在一个创建一个组的表达式的一部分时,你可以在我们的例子中使用它,所以我们使用它,这样我们就可以通过put来定义我们想要成为可选模式的一部分*旁边,以便它可以出现零次或多次。

好的把所有人放在一起:

第一部分[^,] *表示:匹配零个或多个不是'或'的字符,'这个匹配字符串如'A1'或'((0.2“

()*中的第二部分用于继续匹配其中包含','和空格但您不想拆分的字符串,此部分是可选的,以便它正确匹配'A1'或'ABC'或'p'。

所以(,* [^,] *)*将匹配零个或多个以','开头的字符串,以及任何数字的''后面跟着一个没有','或''的字符串。所以在你的例子中,它将匹配“,0)”这是“((0.2”并且也匹配“,(1.5”和再次“,0))”的延续,这将全部加在一起使得“((0.2) ,0),(1.5,0))“

注意:您可能需要根据正在使用的正则表达式库转义表达式中的某些字符。该解决方案适用于此在线测试人员http://www.regexpal.com/

但是有些库和工具需要你去逃避(

因此表达式如下:

 [^, ]*\(, *[^, ]*\)*

此外,我删除了(| $)部分只有在你希望结束空间成为匹配的一部分时才需要它。