Проверка целочисленной части строки - PullRequest
0 голосов
/ 18 февраля 2019

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

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

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

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 ]

0 голосов
/ 18 февраля 2019

Другой пример использования 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 /а / 2b0e088e6ed0576b

0 голосов
/ 18 февраля 2019

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

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

Объяснение:

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

Demo1

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

^\s*(\d+)

Demo2

...