Использование регулярных выражений с С++ в Unix

Я знаком с самим Regex, но всякий раз, когда я пытаюсь найти какие-либо примеры или документацию для использования regex с компьютерами Unix, я просто получаю учебники о том, как писать регулярное выражение или как использовать специальные библиотеки .NET, доступные для Windows. Я искал какое-то время, и я не могу найти никаких хороших руководств по регулярному выражению С++ на машинах Unix.

Что я пытаюсь сделать:

Разбирайте строку, используя регулярное выражение, разбивая ее, а затем читайте разные подгруппы. Чтобы сделать аналогию с PHP, что-то вроде preg_match, которое возвращает все совпадения $.

Ответ 1

Рассмотрим использование Boost.Regex.

Пример (с сайта):

bool validate_card_format(const std::string& s)
{
   static const boost::regex e("(\\d{4}[- ]){3}\\d{4}");
   return regex_match(s, e);
}

Другой пример:

// match any format with the regular expression:
const boost::regex e("\\A(\\d{3,4})[- ]?(\\d{4})[- ]?(\\d{4})[- ]?(\\d{4})\\z");
const std::string machine_format("\\1\\2\\3\\4");
const std::string human_format("\\1-\\2-\\3-\\4");

std::string machine_readable_card_number(const std::string s)
{
   return regex_replace(s, e, machine_format, boost::match_default | boost::format_sed);
}

std::string human_readable_card_number(const std::string s)
{
   return regex_replace(s, e, human_format, boost::match_default | boost::format_sed);
}

Ответ 2

Посмотрите документацию для регулярных выражений TR1 или (почти эквивалентно) boost regex. Оба работают очень хорошо на разных Unix-системах. Классы регулярных выражений TR1 были приняты в С++ 0x, поэтому, хотя они еще не являются частью стандарта, они будут достаточно скоро.

Изменить: Чтобы разбить строку на подгруппы, вы можете использовать sregex_token_iterator. Вы можете указать либо то, что вы хотите, либо как токены, либо то, что вы хотите, чтобы они соответствовали разделителям. Здесь приведена краткая демонстрация обоих:

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

int main() { 

    std::string line;

    std::cout << "Please enter some words: " << std::flush;
    std::getline(std::cin, line);

    std::tr1::regex r("[ .,:;\\t\\n]+");
    std::tr1::regex w("[A-Za-z]+");

    std::cout << "Matching words:\n";
    std::copy(std::tr1::sregex_token_iterator(line.begin(), line.end(), w),
        std::tr1::sregex_token_iterator(), 
        std::ostream_iterator<std::string>(std::cout, "\n"));

    std::cout << "\nMatching separators:\n";
    std::copy(std::tr1::sregex_token_iterator(line.begin(), line.end(), r, -1), 
        std::tr1::sregex_token_iterator(), 
        std::ostream_iterator<std::string>(std::cout, "\n"));

    return 0;
}

Если вы укажете его следующим образом: "Это текст 999", результат выглядит следующим образом:

Matching words:
This
is
some
text

Matching separators:
This
is
some
999
text

Ответ 3

Вы ищете regcomp, regexec и regfree.

Осторожно, что регулярные выражения Posix на самом деле реализуют два разных языка, обычные (по умолчанию) и расширенные (включая флаг REG_EXTENDED в вызове regcomp). Если вы пришли из мира PHP, расширенный язык ближе к тому, к чему вы привыкли.

Ответ 4

Для perl-совместимых регулярных выражений (pcre/preg) я предлагаю boost.regex.

Ответ 5

Лучше всего было бы boost:: regex.

Ответ 6

Попробуйте pcre. И pcrepp.

Ответ 7

Не стесняйтесь взглянуть на этот небольшой инструмент grep grep, который я написал.

В github

Он использует regcomp, regexec и regfree, о которых говорит R Samuel Klatchko.