0

我在一个项目中使用 VC++ 10。作为 C/C++ 的新手,我刚刚在 Google 上搜索过,似乎标准C++ 中没有正则表达式?VC++ 10 似乎有正则表达式。但是,如何进行正则表达式拆分?我需要为此提升吗?

在网上搜索,我发现许多人推荐 Boost 用于许多事情,标记/拆分字符串,解析(PEG),现在甚至是正则表达式(尽管这应该内置......)。我可以得出结论,提升是必须的吗?它的 180MB 仅用于琐碎的事情,在许多语言中都天真地支持?

4

2 回答 2

7

C++11 标准有std::regex. 它也包含在TR1 for Visual Studio 2010. 实际上 TR1 从 VS2008 开始可用,它隐藏在std::tr1命名空间下。因此,对于 VS2008 或更高版本,您不需要 Boost.Regex。

可以使用以下方法执行拆分regex_token_iterator

#include <iostream>
#include <string>
#include <regex>

const std::string s("The-meaning-of-life-and-everything");
const std::tr1::regex separator("-");
const std::tr1::sregex_token_iterator endOfSequence;

std::tr1::sregex_token_iterator token(s.begin(), s.end(), separator, -1);
while(token != endOfSequence) 
{
   std::cout << *token++ << std::endl;
}

如果您还需要获取分隔符本身,则可以从sub_match指向的对象中获取它token,它是包含令牌的开始和结束迭代器的对。

while(token != endOfSequence) 
{
   const std::tr1::sregex_token_iterator::value_type& subMatch = *token;
   if(subMatch.first != s.begin())
   {
      const char sep = *(subMatch.first - 1);
      std::cout << "Separator: " << sep << std::endl;
   }

   std::cout << *token++ << std::endl;
}

这是您有单个字符分隔符时的示例。如果分隔符本身可以是任何子字符串,则您需要做一些更复杂的迭代器工作并可能存储以前的标记子匹配对象。

或者您可以使用正则表达式组并在第一组中放置分隔符,在第二组中放置真正的标记:

const std::string s("The-meaning-of-life-and-everything");
const std::tr1::regex separatorAndStr("(-*)([^-]*)");
const std::tr1::sregex_token_iterator endOfSequence;

// Separators will be 0th, 2th, 4th... tokens 
// Real tokens will be 1th, 3th, 5th... tokens 
int subMatches[] = { 1, 2 };
std::tr1::sregex_token_iterator token(s.begin(), s.end(), separatorAndStr, subMatches);
while(token != endOfSequence) 
{
   std::cout << *token++ << std::endl;
}

不确定它是否 100% 正确,但只是为了说明这个想法。

于 2012-10-24T12:38:12.427 回答
0

这里是这个博客的一个例子。

你会得到你所有的比赛res

std::tr1::cmatch res;
str = "<h2>Egg prices</h2>";
std::tr1::regex rx("<h(.)>([^<]+)");
std::tr1::regex_search(str.c_str(), res, rx);
std::cout << res[1] << ". " << res[2] << "\n";
于 2012-10-24T13:02:59.007 回答