это регулярное выражение не в состоянии проанализировать все действительные числа с плавающей запятой - PullRequest
1 голос
/ 24 марта 2012

Я пытаюсь найти все плавающие числа (может быть в экспоненциальной форме с префиксом - / + или нет). Например, следующий формат является допустимым: -1.2 +1.2 .2 -3 3E4 -3e5 e-5

Источник текста содержит несколько чисел, разделенных пробелом или запятой. Мне нужно использовать регулярное выражение, чтобы сказать

  1. скажите, есть ли недопустимый номер (например, 1.2 3.2 s3) s3 не является допустимым
  2. список каждого действительного номера

Я понятия не имею, как выполнить (1), но для (2) я использую boost :: regex и следующий код

wstring strre("[-+]?\\b[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?\\b");
wstring src("1.2 -3.4 3.2 3 2 1e-3 3e3");
boost::wregex regexp(strre);
boost::match_results<std::wstring::const_iterator> what; 
regex_search(src, what, regexp, boost::match_continuous);
wcout << "RE: " << strre << endl << endl;
wcout << "SOURCE: [" << src << "]" << endl;

for (int i=0; i<what.size(); i++)
  wcout << "OUTPUT: [" << wstring(what[i].first, what[i].second) << "]"<< endl;

Но этот код показывает мне только первое число (1.2). Я также пробую boost :: match_all, boost :: match_default, тот же результат.

ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ: Привет всем, давайте не будем беспокоиться о проблеме двойной обратной косой черты, это правильно выражено в моем коде (потому что в моем тестовом коде я читаю строку из текста не явной строкой). В любом случае, я изменяю код следующим образом

wstring strre("[-+]?\\b[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?\\b");
boost::wregex regexp(strre);
boost::match_results<std::wstring::const_iterator> what; 
wcout << "RE: " << strre << endl << endl;
while (src.length()>0)
{
  wcout << "SOURCE: [" << src << "]" << endl;
  regex_search(src, what, regexp, boost::match_default);
  wcout << "OUTPUT: [" << wstring(what[0].first, what[0].second) << endl;
  src = wstring(what[0].second, src.end());
}

Теперь корректно отображаются все отдельные числа, но мне приходится запускать regex_search несколько раз, потому что он дает только одно число за раз. Ну, я просто не понимаю, почему regex_search не даст мне все результаты вместо этого. Можно ли запустить поиск один раз и получить все результаты обратно?

1 Ответ

2 голосов
/ 24 марта 2012

Обычно вам нужно дважды экранировать символы обратной косой черты в строке C ++. Таким образом, ваш "\." превращается в .. Вам нужно, чтобы он был "\\." и т. Д. Точно так же ваш "\b" становится не границей слов, а буквальным возвратом! Исправьте так же: "\\b".

Кроме того, где документация для этого strre класса? Вы уверены, что он понимает язык, который вы используете?

Очевидно, новый стандарт C ++ имеет необработанные строковые литералы. Они работают как строки `backticked` в Go или как строки 'одинарные кавычки' или / pattern / в Perl. Подробнее см. в этом ответе .

EDIT

Вот несколько более причудливый шаблон для обнаружения литералов с плавающей точкой, но без обратной косой черты:

 [+-]?(?=[.]?[0-9])[0-9]*(?:[.][0-9]*)?(?:[Ee][+-]?[0-9]+)?

Обратите внимание, что для этого требуются предварительные просмотры, которые ERE не поддерживают. Вы, вероятно, должны использовать библиотеку PCRE , которая делает. Разбитый, это

[+-]?                   # optional leading sign
(?=[.]?[0-9])           # lookahead for a digit, maybe with an intervening dot
[0-9]*                  # maybe some digits
(?:[.][0-9]*)?          # maybe a (dot plus maybe some digits)
(?:[Ee][+-]?[0-9]+)?    # maybe an exponent, which may have a sign and must have digits

Шаблон любезно предоставлен библиотекой Perl Regexp :: Common .

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