linux: странное поведение регулярных выражений [дубликат]

Ваш путь к классу нарушен (что является общей проблемой very в мире Java).

В зависимости от того, как вы запускаете свое приложение, вам нужно пересмотреть аргумент в -cp, запись в Class-Path в файле MANIFEST.MF или на вашем диске.

89
задан T.C. 27 September 2015 в 04:24
поделиться

3 ответа

<regex> был реализован и выпущен в GCC 4.9.0.

В вашей (более старой) версии GCC это не реализовано .

] Этот прототип кода <regex> был добавлен, когда вся поддержка GCC C ++ 0x была очень экспериментальной, отслеживая ранние C ++ 0x черновики и предоставляя людям возможность экспериментировать. Это позволяло людям находить проблемы и давать обратную связь стандартным комитетом до того, как стандарт был доработан. В то время многие люди были благодарны за то, что имели доступ к возможностям кровотечения задолго до того, как C ++ 11 был закончен, и еще до того, как многие другие компиляторы предоставили любую поддержку , и эта обратная связь действительно помогла улучшить C ++ 11 , Это был хороший ThingTM.

Код <regex> никогда не был в полезном состоянии, но был добавлен как работа в процессе, как и многие другие биты кода в то время.

Это часто работает с открытым исходным кодом: Release early, release часто - к сожалению, в случае <regex> мы получили только раннюю часть, а не часто часть, которая завершила бы реализацию.

Большинство частей библиотеки были более полными и теперь почти полностью реализованы, но <regex> не были, поэтому он остался в том же незавершенном состоянии, поскольку он был добавлен.

Серьезно, хотя кто-то, кто отправляет реализацию regex_search, которая только делает «return false», была хорошей идеей?

Это была не такая плохая идея несколько лет назад , когда C ++ 0x все еще продолжал работу, и мы отправили множество частичных реализаций. Никто не думал, что он останется непригодным для использования так долго, поэтому, оглядываясь назад, возможно, он должен был быть отключен, и для его включения требуется макрос или встроенная опция. Но этот корабль давно отплыл. Есть экспортированные символы из библиотеки libstdc ++, поэтому , которые зависят от кода регулярного выражения, поэтому просто удалить его (в, скажем, GCC 4.8) не было бы тривиально.

158
ответ дан Lightness Races in Orbit 21 August 2018 в 14:28
поделиться
  • 1
    Запустить его? Я поддерживаю его. Поверьте мне, это не реализовано. Это экспериментальный, незавершенный прототип с нефункциональными заглушками для большинства функций. Если вы считаете, что это реализовано, я надеюсь, что никогда не буду использовать ваш код. – Jonathan Wakely 1 October 2012 в 15:39
  • 2
    : D ОК, извините за грубые. Я из «если он не реализован, почему он даже там?» школа мысли, но, возможно, это просто другая точка зрения. Я видел функции, поэтому я использовал их, полагая, что они будут работать. – tunnuz 1 October 2012 в 15:56
  • 3
    См. Мой отредактированный ответ, который пытается объяснить, почему код был добавлен до его использования. – Jonathan Wakely 1 October 2012 в 18:54
  • 4
    @JonathanWakely, спасибо вам за понимание идеи и процесса разработки GCC. – tunnuz 2 October 2012 в 08:30
  • 5
    Зачем беспокоиться о таких флагах, как «- std = c ++ 11». если компилятор может делать все, что захочет? Добавить "экспериментальный" флаг, чтобы получить экспериментальные функции, или что-то вроде «- std = c ++ 11exp». Когда запрашивается стандартное поведение, и стандартная функция, как известно, не реализуется, указывается предупреждение или ошибка времени компиляции. В противном случае люди пытаются «отлаживать». их код против стандарта, и только после некоторого времени исследования выяснилось, что стандарт не реализован. – Brent Baccala 23 September 2015 в 06:45

В этот момент (с использованием std = c ++ 14 в g ++ (GCC) 4.9.2) все еще не принимается regex_match.

Вот подход, который работает как regex_match, но вместо этого использует sregex_token_iterator. И он работает с g ++.

string line="1a2b3c";
std::regex re("(\\d)");
std::vector<std::string> inVector{
    std::sregex_token_iterator(line.begin(), line.end(), re, 1), {}
};

//prints all matches
for(int i=0; i<inVector.size(); ++i)
    std::cout << i << ":" << inVector[i] << endl;

он будет печатать 1 2 3

, вы можете прочитать ссылку sregex_token_iterator в: http://en.cppreference.com/ ж / CPP / регулярное выражение / regex_token_iterator

0
ответ дан Luis Orantes 21 August 2018 в 14:28
поделиться
  • 1
    "В этот момент (с использованием std = c ++ 14 в g ++ (GCC) 4.9.2) по-прежнему не принимается regex_match. & quot; Это неверно, вы, вероятно, используете его неправильно. – Jonathan Wakely 29 September 2017 в 11:45
  • 2
    Ваш код не является "подходом, который работает как regex_match & quot; потому что эта функция пытается сопоставить подстроки, а не целую строку, поэтому я все еще думаю, что вы используете ее неправильно. Вы можете сделать это с помощью std::regex_search, хотя, см. wandbox.org/permlink/rLbGyYcYGNsBWsaB – Jonathan Wakely 29 September 2017 в 11:58
  • 3
    C ++ 14 (gcc 6.3): 0:1 1:2 2:3 ideone.com/FvyQfh – wp78de 8 April 2018 в 03:52

Обнаружение функции

Это фрагмент, чтобы определить, реализована ли реализация libstdc++ с препроцессором C:

#include <regex>
#if __cplusplus >= 201103L &&                             \
    (!defined(__GLIBCXX__) || (__cplusplus >= 201402L) || \
        (defined(_GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT) || \
         defined(_GLIBCXX_REGEX_STATE_LIMIT)           || \
             (defined(_GLIBCXX_RELEASE)                && \
             _GLIBCXX_RELEASE > 4)))
#define HAVE_WORKING_REGEX 1
#else
#define HAVE_WORKING_REGEX 0
#endif

Макросы

Тестирование

Вы можете протестировать его с помощью GCC следующим образом:

cat << EOF | g++ --std=c++11 -x c++ - && ./a.out
#include <regex>

#if __cplusplus >= 201103L &&                             \
    (!defined(__GLIBCXX__) || (__cplusplus >= 201402L) || \
        (defined(_GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT) || \
         defined(_GLIBCXX_REGEX_STATE_LIMIT)           || \
             (defined(_GLIBCXX_RELEASE)                && \
             _GLIBCXX_RELEASE > 4)))
#define HAVE_WORKING_REGEX 1
#else
#define HAVE_WORKING_REGEX 0
#endif

#include <iostream>

int main() {
  const std::regex regex(".*");
  const std::string string = "This should match!";
  const auto result = std::regex_search(string, regex);
#if HAVE_WORKING_REGEX
  std::cerr << "<regex> works, look: " << std::boolalpha << result << std::endl;
#else
  std::cerr << "<regex> doesn't work, look: " << std::boolalpha << result << std::endl;
#endif
  return result ? EXIT_SUCCESS : EXIT_FAILURE;
}
EOF

Результаты

Вот некоторые результаты для разных компиляторов:


$ gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-11)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ ./a.out
<regex> doesn't work, look: false

$ gcc --version
gcc (GCC) 6.2.1 20160830
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ ./a.out
<regex> works, look: true

$ gcc --version
gcc (Debian 4.9.2-10) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ ./a.out
<regex> works, look: true

$ gcc --version
gcc (Ubuntu 6.2.0-5ubuntu12) 6.2.0 20161005
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ ./a.out
<regex> works, look: true

$ gcc --version
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ ./a.out
<regex> works, look: true

$ gcc --version
gcc (GCC) 6.2.1 20160830
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ clang --version
clang version 3.9.0 (tags/RELEASE_390/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
$ ./a.out  # compiled with 'clang -lstdc++'
<regex> works, look: true

Здесь будут Dragons

Это абсолютно неподдерживается и полагается об обнаружении частных макросов, которые разработчики GCC поместили в заголовки bits/regex*. Они могут меняться и уходить в в любое время . Надеюсь, они не будут удалены в текущих версиях 4.9.x, 5.x, 6.x, но они могут исчезнуть в версиях 7.x.

Если разработчики GCC добавили #define _GLIBCXX_HAVE_WORKING_REGEX 1 (или что-то, подсказка hint nudge nudge) в релизе 7.x, который сохранился, этот фрагмент можно было обновить, включив его, а последующие выпуски GCC будут работать со сниппетом выше.

Насколько я знаю , все остальные компиляторы работают <regex>, когда __cplusplus >= 201103L, но YMMV.

Очевидно, что это полностью нарушится, если кто-то определит макросы _GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT или _GLIBCXX_REGEX_STATE_LIMIT вне заголовков stdc++-v3.

9
ответ дан Matt Clarkson 21 August 2018 в 14:28
поделиться
  • 1
    Очень хорошо! Я собирался предложить проверить макрос защиты заголовка из одного из заголовков, который является новым в GCC 4.9, но у них нет охранников: - \ Макросы не изменяются для GCC 7, но теоретически они могут сделать для GCC 8+, поэтому, пожалуйста, напишите запрос на улучшение в gcc.gnu.org/bugzilla с запросом чего-то вроде _GLIBCXX_REGEX_IS_OK_NOW_KTHXBAI в заголовках, поэтому он не забывается - спасибо! – Jonathan Wakely 16 December 2016 в 19:06
  • 2
    @JonathanWakely добавил 78905 . Я не уверен, как сделать это в улучшенной ошибке, но сейчас она в системе. – Matt Clarkson 22 December 2016 в 18:40
Другие вопросы по тегам:

Похожие вопросы: