验证字符串的整数部分
Validating integer part of an string
我有一个文本文件,我需要将每一行转换为整数。
行可以以“#”开头以表示注释。此外,在数据之后它也可能是内联注释......再次由'#'
指示
所以我有下面的例子:
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”。如何找出最后一个无效?
所以我的意思是处理此任务的最佳防错代码是什么?
您可以使用此正则表达式验证并从将捕获您的号码的第一个分组模式中提取数字,
^\s*(\d+)\b(?!\.)
解释:
^
- 字符串开始
\s*
- 允许在数字 前可选 space
(\d+)
- 捕获数字并将其放入第一个分组模式
\b
- 确保数字在较大文本中不部分匹配,因为前面存在负面展望
(?!\.)
- 如果数字后面有小数,则拒绝匹配
如果只有最后一个无效,您可以使用此正则表达式从前三个条目中捕获数字,
^\s*(\d+)
使用 std::regex
的另一个示例。将 QString
转换为 string_view
留作 reader.
的练习
#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
我有一个文本文件,我需要将每一行转换为整数。
行可以以“#”开头以表示注释。此外,在数据之后它也可能是内联注释......再次由'#'
指示所以我有下面的例子:
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”。如何找出最后一个无效?
所以我的意思是处理此任务的最佳防错代码是什么?
您可以使用此正则表达式验证并从将捕获您的号码的第一个分组模式中提取数字,
^\s*(\d+)\b(?!\.)
解释:
^
- 字符串开始\s*
- 允许在数字 前可选 space
(\d+)
- 捕获数字并将其放入第一个分组模式\b
- 确保数字在较大文本中不部分匹配,因为前面存在负面展望(?!\.)
- 如果数字后面有小数,则拒绝匹配
如果只有最后一个无效,您可以使用此正则表达式从前三个条目中捕获数字,
^\s*(\d+)
使用 std::regex
的另一个示例。将 QString
转换为 string_view
留作 reader.
#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