С++ regex_replace для очистки конкатенированных десятичных чисел

В рамках очистки строки данных пути SVG для отображения я хочу добавить пробелы между конкатенированными дробными числами.

Например, «0.1.20» должно стать «0.1 .20» — в основном добавьте пробел перед второй десятичной точкой, если у вас есть 2 десятичных точки, разделенные только одним или несколькими десятичными числами (т.е. «2.0» не должно стать «2 .0")

Я пробовал следующее:

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

void splitString(std::string& pathString) {

  // ... some other clean-up, which works ...

  std::regex re3("(\\.[:digit:]+)(\\.)");$
  pathString = std::regex_replace(pathString, re3, "$1 $2");$

  std::cout << pathString << std::endl;$
}

Но когда я передаю строку с конкатенированными десятичными знаками, например

M 46 -38.9 q 3.7.15 7.65.45 1.2.1 2.35.25 2.75.3 5.05.85 3.85.9 6.5 2.4

он не меняется в строке журнала cout. Я использую аналогичные регулярные выражения для очистки других элементов строки, и все они работают правильно, поэтому я предполагаю, что это что-то, непосредственно связанное с самим регулярным выражением.


person patros    schedule 19.10.2019    source источник


Ответы (1)


Перепробовал еще несколько вещей и нашел то, что сработало.

Добавление класса символов вокруг [:digit:] решило проблему.

std::regex re3("(\\.[[:digit:]]+)(\\.)");

[:digit:] по-видимому, является диапазоном классов, который должен быть обернут в класс символов, чтобы быть проанализированным как атом.

person patros    schedule 19.10.2019
comment
Если вы хотите добавить ссылку на этот ответ: en.cppreference.com/w /cpp/regex/ecmascript#Character_classes - person JaMiT; 19.10.2019
comment
Отличная идея! Но это все равно не работает правильно, верно? В смысле 5.05.85 надо конвертировать в 5.0 5.85 а не 5.05 .85? - person anatolyg; 19.10.2019
comment
@anatolyg Нет, спецификация SVG определяет жадное сопоставление, поэтому многие цифры, насколько это возможно, идут к первому номеру; 5.05.85 следует интерпретировать как 5.05, за которым следует .85. - person JaMiT; 20.10.2019
comment
@JaMiT Я не уверен, что это та ссылка, которую вы хотели опубликовать (вы имели в виду ТАК ответ?). Я все еще немного смущен, почему диапазон символов POSIX нельзя рассматривать как атом, TBH. - person patros; 20.10.2019
comment
@patros Хм ... Может быть, вы неправильно прочитали этот ответ в моем первом комментарии? Когда я сказал этот ответ, я имел в виду ответ, который я комментировал (т.е. ваш ответ прямо здесь); Я не имел в виду, что ссылка была на ответ. Ссылка есть на ссылку. (Если вы предпочитаете, я мог бы опубликовать свой собственный ответ, но я подумал, что сначала дам вам возможность улучшить свой ответ.) - person JaMiT; 20.10.2019
comment
@JaMiT Я прочитал ссылку, и я действительно не мог понять, почему это ведет себя так, как в документации. То же самое по второй ссылке. Я не эксперт по регулярным выражениям, теперь я вижу, как это работает, но мне трудно разобрать документацию. Не стесняйтесь писать ответ, если хотите. - person patros; 20.10.2019
comment
@patros Я еще раз изучил это, и оказалось, что даже регулярные выражения POSIX требуют двойных скобок - выбор грамматики был отвлекающим маневром. То, что вы добавили к своему ответу, достаточно хорошо. - person JaMiT; 20.10.2019