Подтвердить что ты не робот

Regex С++: извлечь подстроку

Я хотел бы извлечь подстроку между двумя другими. ex: /home/toto/FILE_mysymbol_EVENT.DAT
или просто FILE_othersymbol_EVENT.DAT
И я хотел бы получить: mysymbol и othersymbol

Я не хочу использовать boost или другие библиотеки. Просто стандартные материалы из С++, кроме CERN ROOT lib, с TRegexp, но я не знаю, как его использовать...

4b9b3361

Ответ 1

С прошлого года С++ имеет регулярное выражение, встроенное в стандарт. Эта программа покажет, как использовать их для извлечения строки, после которой:

#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 года) все современные компиляторы С++ и их стандартные библиотеки полностью обновлены стандартом С++ 11, а также большинство, если не все из С++ 14. GCC 6 и предстоящий Clang 4 поддерживают большую часть следующего стандарта С++ 17.

Ответ 2

TRegexp поддерживает только очень ограниченное подмножество регулярных выражений по сравнению с другими ароматами regex. Это делает создание одного регулярного выражения, которое удовлетворяет вашим потребностям несколько неудобно.

Одно из возможных решений:

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

будет соответствовать строке до первого символа подчеркивания, а затем захватить все символы до следующего подчеркивания. Соответствующий результат матча затем найдется в группе № 1.

Но в вашем случае зачем использовать регулярное выражение? Просто найдите первое и второе вхождение разделителя _ в строке и извлеките символы между этими позициями.

Ответ 3

Если вы хотите использовать регулярные выражения, я бы рекомендовал использовать регулярные выражения С++ 11 или, если у вас есть компилятор, который еще не поддерживает их, Boost. Boost - это то, что я считаю почти частью стандартного С++.

Но для этого конкретного вопроса вам не нужны никакие формы регулярных выражений. Что-то вроде этого эскиза должно работать нормально, после того, как вы добавите все соответствующие проверки ошибок (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.