The following regex-based function supports both signed integer literals and decimal literals in standard and scientific notation (e.g. 42
, 3.14
, -1
, +58.
, 4e2
, 1.e-2
, -12.34e-56
, .1E4
). Integers prefixed with zeros are also matched (e.g. 0001
):
#include <string_view>
#include <regex>
bool is_number(std::string_view s) {
static std::regex const re{
R"([-+]?((\.\d+)|(\d+\.)|(\d+))\d*([eE][-+]?\d+)?)"};
return std::regex_match(s.data(), re);
}
Hexadecimal literals, binary literals, single-quote separators and suffixes (f
, F
, l
, L
, u
, U
, ll
, LL
, Z
) are not matched.
Below are some unit tests using gtest. The complete code is available at https://godbolt.org/z/vbTnMx7or
TEST(IsNumber, True) {
char const *tests[]{"42", "3.14", "-0", "+4", ".3",
"+.5", "-.23", "7.", "1e2", "1.e2",
"1.0e-2", "8.e+09", "2E34", "61e2", "-0e1",
"+0E+10", "-.01E-5", "07", "+01E1", "12.34"};
for (auto const &x : tests) {
EXPECT_TRUE(is_number(x));
}
}
TEST(IsNumber, False) {
char const *tests[]{"4e", "xyz", ".3.14", "--0", "2-4",
"..3", ".+5", "7 2", "1f", "1.0f",
"1e-2.0", "8e+0e1", "2E.4", "a", "e15",
"-0e10.3", ".e2", "+1.2E0e", "1.2+3", "e1"};
for (auto const &x : tests) {
EXPECT_FALSE(is_number(x));
}
}
if (expr) return true; return false;
! Just writereturn expr;
. – Aldisif (expr) return expr; else return expr;
,if (expr == true)
,(if expr != false)
, orif ((expr == true) == true)
. They all introduce complexity that does not benefit the writer, reader, or compiler of the code. The elimination of needless complexity is not a shortcut; it's key to writing better software. – Vannessavanni