Использование регулярных выражений с C ++ в Unix - PullRequest
10 голосов
/ 08 февраля 2010

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

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

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

Ответы [ 8 ]

13 голосов
/ 08 февраля 2010

Рассмотрите возможность использования 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);
}
9 голосов
/ 08 февраля 2010

Посмотрите документацию для регулярных выражений TR1 или (почти эквивалентно) регулярных выражений. Оба прекрасно работают на разных системах Unix. Классы регулярных выражений TR1 были приняты в C ++ 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
0 голосов
/ 09 февраля 2010

Я использую "GNU regex": http://www.gnu.org/s/libc/manual/html_node/Regular-Expressions.html

Работает хорошо, но не может найти четкого решения для регулярного выражения UTF-8.

Привет

0 голосов
/ 08 февраля 2010

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

В GitHub

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

0 голосов
/ 08 февраля 2010

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

0 голосов
/ 08 февраля 2010

Моя лучшая ставка будет boost :: regex .

0 голосов
/ 08 февраля 2010

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

0 голосов
/ 08 февраля 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...