正则表达式 C:提取子字符串

新手上路,请多包涵

我想在另外两个之间提取一个子字符串。

例如: /home/toto/FILE_mysymbol_EVENT.DAT

或者只是 FILE_othersymbol_EVENT.DAT

我想得到: mysymbolothersymbol

我不想使用 boost 或其他库。只是来自 C++ 的标准东西,除了 CERN 的 ROOT 库,带有 TRegexp ,但我不知道如何使用它……

原文由 eouti 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.2k
2 个回答

自去年以来,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';
}

它将输出:

匹配:mysymbol

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


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

原文由 Some programmer dude 发布,翻译遵循 CC BY-SA 3.0 许可协议

一些程序员老兄、Tim Pietzcker 和 Christopher Creutzig 的答案很酷且正确,但在我看来,它们对于初学者来说并不是很明显。

下面的函数是试图为一些程序员老兄和 Tim Pietzcker 的答案创建一个辅助插图:

 void ExtractSubString(const std::string& start_string
    , const std::string& string_regex_extract_substring_template)
{
    std::regex regex_extract_substring_template(
        string_regex_extract_substring_template);

    std::smatch match;

    std::cout << std::endl;

    std::cout << "A substring extract template: " << std::endl;
    std::cout << std::quoted(string_regex_extract_substring_template)
        << std::endl;

    std::cout << std::endl;

    std::cout << "Start string: " << std::endl;
    std::cout << start_string << std::endl;

    std::cout << std::endl;

    if (std::regex_search(start_string.begin(), start_string.end()
       , match, regex_extract_substring_template))
    {
        std::cout << "match0: " << match[0] << std::endl;
        std::cout << "match1: " << match[1] << std::endl;
        std::cout << "match2: " << match[2] << std::endl;
    }

    std::cout << std::endl;
}

以下重载函数试图帮助说明 Christopher Creutzig 的答案:

 void ExtractSubString(const std::string& start_string
    , const std::string& before_substring, const std::string& after_substring)
{
    std::cout << std::endl;

    std::cout << "A before substring: " << std::endl;
    std::cout << std::quoted(before_substring) << std::endl;

    std::cout << std::endl;

    std::cout << "An after substring: " << std::endl;
    std::cout << std::quoted(after_substring) << std::endl;

    std::cout << std::endl;

    std::cout << "Start string: " << std::endl;
    std::cout << start_string << std::endl;

    std::cout << std::endl;

    size_t before_substring_begin
        = start_string.find(before_substring);
    size_t extract_substring_begin
        = before_substring_begin + before_substring.size();
    size_t extract_substring_end
        = start_string.find(after_substring, extract_substring_begin);

    std::cout << "Extract substring: " << std::endl;
    std::cout
    << start_string.substr(extract_substring_begin
       , extract_substring_end - extract_substring_begin)
    << std::endl;

    std::cout << std::endl;
}

这是运行重载函数的主要函数:

 #include <regex>
#include <iostream>
#include <iomanip>

int main()
{
    const std::string start_string
        = "/home/toto/FILE_mysymbol_EVENT.DAT";

    const std::string string_regex_extract_substring_template(
        ".*FILE_(\\w+)_EVENT\\.DAT.*");
    const std::string string_regex_extract_substring_template2(
        "[^_]*_([^_]*)_");

    ExtractSubString(start_string, string_regex_extract_substring_template);

    ExtractSubString(start_string, string_regex_extract_substring_template2);

    const std::string before_substring = "/home/toto/FILE_";
    const std::string after_substring = "_EVENT.DAT";

    ExtractSubString(start_string, before_substring, after_substring);
}

这是执行 main 函数的结果:

 A substring extract template:
".*FILE_(\\w+)_EVENT\\.DAT.*"

Start string:
"/home/toto/FILE_mysymbol_EVENT.DAT"

match0: /home/toto/FILE_mysymbol_EVENT.DAT
match1: mysymbol
match2:

A substring extract template:
"[^_]*_([^_]*)_"

Start string:
"/home/toto/FILE_mysymbol_EVENT.DAT"

match0: /home/toto/FILE_mysymbol_
match1: mysymbol
match2:

A before substring:
"/home/toto/FILE_"

An after substring:
"_EVENT.DAT"

Start string:
"/home/toto/FILE_mysymbol_EVENT.DAT"

Extract substring:
mysymbol

原文由 Vitalii 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题