有没有办法丢弃空的捕获?

时间:2016-08-02 15:24:44

标签: c++ regex string iterator spinach

是否有内置方法只迭代非空捕获或我是否需要使用lambda /修改我的正则表达式?

例如,给定:const auto input = "Peas&Carrots Spinach-Casserole Beets Pizza Spinach-Salad Coleslaw"s我想找到包含“菠菜”的食物。所以我可以这样做:

const regex re{ "\\s*(?:\\S*Spinach\\S*|(\\S*))" };

copy(sregex_token_iterator(cbegin(input), cend(input), re, 1), sregex_token_iterator(), ostream_iterator<string>(cout, "\n"));

问题当然是I get an output喜欢:

  

豌豆&安培;胡萝卜
  
  甜菜
  比萨
  
  凉拌

有解决方法吗?

3 个答案:

答案 0 :(得分:1)

显而易见的方法是使用std::copy_if(或std::remove_copy_if)并仅在字符串非空时复制字符串。

remove_copy_if(
    sregex_token_iterator(cbegin(input), cend(input), re, 1),  
    sregex_token_iterator(), 
    ostream_iterator<string>(cout, "\n"),
    [](string const &s) { return s.empty(); } 
);

答案 1 :(得分:1)

您可以使用std::copy_if和lambda来检查正则表达式匹配中的字符串是否为空。使用

copy_if(sregex_token_iterator(cbegin(input), cend(input), re, 1), 
        sregex_token_iterator(), ostream_iterator<string>(cout, "\n"), 
        [](const std::string& match){ return !match.empty(); });

我们得到了

Peas&Carrots
Beets
Pizza
Coleslaw

Live Example

因为它只会打印非空字符串。

答案 2 :(得分:0)

从那些比我更聪明的答案中,似乎实际上没有办法在没有lambda的情况下丢弃空结果。在这个问题中,有几种选择:

  1. 使用前瞻,这有点贵,但只捕获没有“菠菜”的单词:
  2. const regex re{ "(?:\\s+|^)(?!Spinach)(\\S+)" };
    
    copy(sregex_token_iterator(cbegin(input), cend(input), re, 1), sregex_token_iterator(), ostream_iterator<string>(cout, "\n"));
    

    Live Example

    1. 使用istream_iterator和lambda,这会消除lambda的很多灵活性,但由于input是以空格分隔的,因此这可能是最佳选择:
    2. istringstream{ input };
      
      copy_if(istream_iterator<string>(cbegin(input), cend(input)), istream_iterator<string>(), ostream_iterator<string>(cout, "\n"), [](const auto& i) { return i.find("Spinach") == string::npos; });
      

      Live Example