Проверка целочисленной части строки
У меня есть текстовый файл, который мне нужно преобразовать каждую строку в целое число.
Строки могут начинаться с "#" для обозначения комментария. Кроме того, после данных это также может быть встроенный комментарий... снова обозначенный знаком "#"
Итак, у меня есть пример ниже:
QString time = "5000 #this is 5 seconds"; // OK
QString time = " 5000 # this is 5 seconds"; // OK..free spaceis allowed at start
QString time = "5000.00 #this is 5 seconds"; // invalid...no decimal
QString time = "s5000 # this is 5 seconds"; // invalid...does not start with numerical character
Как я могу позаботиться об этих случаях? Я имею в виду во всех 4 приведенных выше примерах, кроме последних двух, мне нужно извлечь "5000". Как узнать, что последний неверен?
Итак, я имею в виду, что является лучшим отказоустойчивым кодом для решения этой задачи?
2 ответа
Еще один пример использования std::regex
, преобразование QString
к string_view
оставлено в качестве упражнения для читателя.
#include <regex>
#include <string_view>
#include <iostream>
#include <string>
#include <optional>
std::optional<std::string> extract_number(std::string_view input)
{
static constexpr char expression[] = R"xx(^\s*(\d+)\s*(#.*)?$)xx";
static const auto re = std::regex(expression);
auto result = std::optional<std::string>();
auto match = std::cmatch();
const auto matched = std::regex_match(input.begin(), input.end(), match, re);
if (matched)
{
result.emplace(match[1].first, match[1].second);
}
return result;
}
void emit(std::string_view candidate, std::optional<std::string> result)
{
std::cout << "offered: " << candidate << " - result : " << result.value_or("no match") << '\n';
}
int main()
{
const std::string_view candidates[] =
{
"5000 #this is 5 seconds",
" 5000 # this is 5 seconds",
"5000.00 #this is 5 seconds",
"s5000 # this is 5 seconds"
};
for(auto candidate : candidates)
{
emit(candidate, extract_number(candidate));
}
}
ожидаемый результат:
offered: 5000 #this is 5 seconds - result : 5000
offered: 5000 # this is 5 seconds - result : 5000
offered: 5000.00 #this is 5 seconds - result : no match
offered: s5000 # this is 5 seconds - result : no match
Вы можете использовать это регулярное выражение для проверки и извлечения цифры из первого шаблона группировки, которая будет захватывать ваш номер,
^\s*(\d+)\b(?!\.)
Объяснение:
^
- начало строки\s*
- Позволяет дополнительное пространство перед номером(\d+)
- захватывает число и помещает его в первый шаблон группировки\b
- Гарантирует, что число не совпадает частично в большом тексте из-за негативного взгляда впереди, присутствующего впереди(?!\.)
- Отклоняет совпадение, если после числа стоит десятичная дробь
В случае, если только последний недействителен, вы можете использовать это регулярное выражение для захвата числа из первых трех записей,
^\s*(\d+)