我想在另外两个之间提取一个子串
例如:/home/toto/FILE_mysymbol_EVENT.DAT
或只是FILE_othersymbol_EVENT.DAT
我希望得到:mysymbol
和othersymbol
我不想使用boost或其他库。只是来自C ++的标准内容,除了CERN的ROOT lib,TRegexp,但我不知道如何使用它......
答案 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 != npos
,end != 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';
是一个很好的候选人。