Regex C ++:提取子字符串

时间:2012-07-24 08:57:59

标签: c++ regex

我想在另外两个之间提取一个子串 例如:/home/toto/FILE_mysymbol_EVENT.DAT
或只是FILE_othersymbol_EVENT.DAT
我希望得到:mysymbolothersymbol

我不想使用boost或其他库。只是来自C ++的标准内容,除了CERN的ROOT lib,TRegexp,但我不知道如何使用它......

4 个答案:

答案 0 :(得分:35)

自去年以来,C ++在标准中内置了正则表达式。该程序将展示如何使用它们来提取您所追求的字符串:

#include <regex>
#include <iostream>

int main()
{
    const std::string s = "/home/toto/FILE_mysymbol_EVENT.DAT";
    std::regex rgx(".*FILE_(\\w+)_EVENT\\.DAT.*");
    std::smatch match;

    if (std::regex_search(s.begin(), s.end(), match, rgx))
        std::cout << "match: " << match[1] << '\n';
}

将输出:

match: mysymbol

应该注意的是,它在GCC中不起作用,因为它对正则表达式的库支持不是很好。在VS2010(可能是VS2012)中运行良好,并且应该在clang中工作。


到现在为止(2016年末),所有现代C ++编译器及其标准库都完全符合C ++ 11标准,大多数(如果不是全部)C ++ 14也是如此。 GCC 6和即将推出的Clang 4也支持大部分即将推出的C ++ 17标准。

答案 1 :(得分:2)

与其他正则表达式相比,TRegexp仅支持非常有限的正则表达式子集。这使得构建一个适合您需求的单一正则表达式有点尴尬。

一种可能的解决方案:

[^_]*_([^_]*)_

将匹配字符串直到第一个下划线,然后捕获所有字符,直到下一个下划线。然后在组号1中找到匹配的相关结果。

但在你的情况下,为什么要使用正则表达式呢?只需在字符串中找到第一个和第二个分隔符_,然后在这些位置之间提取字符。

答案 2 :(得分:2)

如果你想使用正则表达式,我真的建议使用C ++ 11的正则表达式,或者,如果你有一个尚不支持它们的编译器,那么Boost。 Boost是我认为几乎是标准C ++的一部分。

但对于这个特殊问题,你并不需要任何形式的正则表达式。在添加所有适当的错误检查(beg != nposend != npos等),测试代码并删除我的拼写错误之后,像这样的草图应该可以正常工作:

std::string between(std::string const &in,
                    std::string const &before, std::string const &after) {
  size_type beg = in.find(before);
  beg += before.size();
  size_type end = in.find(after, beg);
  return in.substr(beg, end-beg);
}

显然,您可以将std::string更改为模板参数,它可以与std::wstring或更少使用std::basic_string的实例化一起使用。

答案 3 :(得分:-1)

我会在信任之前研究一些极端情况,但是

   std::string text = "/home/toto/FILE_mysymbol_EVENT.DAT";
   std::regex re("(.*)(FILE_)(.*)(_EVENT.DAT)(.*)");
   std::cout << std::regex_replace(text, re, "$3") << '\n';

是一个很好的候选人。

相关问题