Проверка целочисленной части строки

У меня есть текстовый файл, который мне нужно преобразовать каждую строку в целое число.

Строки могут начинаться с "#" для обозначения комментария. Кроме того, после данных это также может быть встроенный комментарий... снова обозначенный знаком "#"

Итак, у меня есть пример ниже:

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

https://coliru.stacked-crooked.com/a/2b0e088e6ed0576b

Вы можете использовать это регулярное выражение для проверки и извлечения цифры из первого шаблона группировки, которая будет захватывать ваш номер,

^\s*(\d+)\b(?!\.)

Объяснение:

  • ^ - начало строки
  • \s* - Позволяет дополнительное пространство перед номером
  • (\d+) - захватывает число и помещает его в первый шаблон группировки
  • \b - Гарантирует, что число не совпадает частично в большом тексте из-за негативного взгляда впереди, присутствующего впереди
  • (?!\.) - Отклоняет совпадение, если после числа стоит десятичная дробь

Demo1

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

^\s*(\d+)

Demo2

Другие вопросы по тегам