如何保证一组特定的字符作为 string_view 参数的输入?
Posted
技术标签:
【中文标题】如何保证一组特定的字符作为 string_view 参数的输入?【英文标题】:How to guarantee a specific set of characters as input to a string_view parameter? 【发布时间】:2020-08-19 17:56:18 【问题描述】:我正在研究一种设计实现,我希望从一组特定字符中选择输入作为其字符串文字表示。
考虑以下一组类:
class enum BaseType
BINARY = 2,
OCTAL = 8,
DECIMAL = 10,
HEXADECIMAL = 16
;
template<BaseType BASE = BaseType::DECIMAL> // Default Template
class Foo
public:
const uint16_t BaseBASE;
private:
std::string digits_;
int64_t integral_value_;
int64_t decimal_value_;
size_t decimal_index_location_;
public:
Foo()
: digits_"",
integral_value_0,
decimal_value_0
decimal_index_location_0
Foo(const std::string_view digit_sequence)
: digits_digit_sequence,
integral_value_0,
decimal_value_0
decimal_index_location0
// set values according to the respective digits
// from the decimal point if one exists
// and set the decimal index location if one exists...
;
我可能不得不对其他尚未确定的非默认类型使用特化。无论如何,我想将每种情况限制为以下字符集,如下所示:
BINARY
:
'0'
, '1'
, '.'
OCTAL
:
['0' - '7']
, '.'
DECIMAL
:
['0' - '9']
, '.'
HEXADECIMAL
:
['0' - '9']
, ['a' - 'f']
, ['A' - 'F']
, '.'
这些对于每种类型都是可接受的输入:
BINARY
:
"010"
、".010"
、"01.0"
、"01.
"等...
OCTAL
:
"012345670"
、".012345670"
、"01.2345670"
、"1."
等...
DECIMAL
:
"01234567890"
、".01234567890"
、"01.234567890"
、"1."
等...
HEXADECIMAL
:
"0123456789abcdef0"
、".0123456789abcdef0"
、"01.23456789abcdef0"
、"1."
等...
"0123456789ABCDEF0"
、".0123456789ABCDEF0"
、"01.23456789ABCDEF0"
、"1."
等...
成为类构造函数的string_view
参数的唯一有效输入字符集。
有没有一种简单、优雅、高效的方法来做到这一点?如果是这样,怎么做?是否通过抛出异常、编译时或运行时断言来处理这并不重要……我只想限制每个模板版本的可能有效字符集……
编辑
对于每种情况,即使单个 '.'
也是有效输入。例如:
Foo a(".");
将被解释为0
,稍后当我合并exponent
部分时,指数将评估为1
,因此结果将是0
,而不是1
,因为电源规则...
【问题讨论】:
使用正则表达式查看输入是否匹配正确的模式? @NathanOliver,我得调查一下,我从来没有真正和regex
合作过这么多......
【参考方案1】:
使用<regex>
,您可以这样做:
static const std::regex binary_regex(R"([01]*\.?[01]*)");
static const std::regex octal_regex(R"([0-7]*\.?[0-7]*)");
static const std::regex decimal_regex(R"([0-9]*\.?[0-9]*)");
static const std::regex hex_regex(R"([0-9a-fA-F]*\.?[0-9a-fA-F]*)");
bool do_match(const std::string& s, const std::regex& regex)
// if (s.empty()) return false;
std::smatch base_match;
return std::regex_match(s, base_match, regex);
Demo
您甚至可以通过分组获得点之前和之后的值
【讨论】:
我喜欢这个建议,只是为了清楚起见,只是一个简单的问题......上面是否只允许一个.
?我不想要 243.4252.342
这样的字符串。
是的,只允许使用一个点,因此只允许使用“”、“00”、“00.”、“00.00”、“.00”等形式的数字。
这只有一个问题......到目前为止一切正常,但是当我传入一个字符串,如 "24526"
没有小数点时,regex
抛出一个未处理的异常。 ..
link 添加,这里没有问题。
在正则表达式 Demo 中使用组的简化版本。请注意,尽管您计算十进制的方式可能不是您对非十进制的期望:二进制中的0.1
是0.25
,即使是十进制前导0
也会丢失0.9。以上是关于如何保证一组特定的字符作为 string_view 参数的输入?的主要内容,如果未能解决你的问题,请参考以下文章
将 std::string_view 与 api 一起使用,期望以 null 终止的字符串