正则表达式匹配双精度数

22

我有一个正则表达式"^[0-9]+\.?[0-9]*$"),用于在Visual C++中匹配双精度数或整数,但它似乎不能工作。 有任何想法吗?

这是我应用代码的方式:

if (System::Text::RegularExpressions::Regex::IsMatch(e0, "^[0-9]+\.?[0-9]*$")){
     e0_val = System::Convert::ToDouble(e0);
}

2
你为什么认为它不起作用?给一个例子。 - Andrew Logvinov
@AndrewLogvinov +1,“不工作,给我代码”不是一个好的问题形式。 - user529758
当我尝试在文本框中使用它来验证数字输入时,它返回一条消息,指示数字0.16不是数字。 - cobie
2
你是否在使用C++/CLI?如果是,为什么不使用Double::TryParse呢? - Mithrandir
@Mithrandir 谢谢你提供的 Double::TryParse...正是我需要的。 - cobie
显示剩余2条评论
7个回答

22

上述正则表达式并不完美,因为它接受了"09"这样的无效数字。更好的表达式应该是:

"^(-?)(0|([1-9][0-9]*))(\\.[0-9]+)?$"

其中:

1. is an optional negative sign;
2. is zero or a valid non-zero integer;
4. is the optional fracture part;
在理论上,断裂部分应该被写成"(\.[0-9]*[1-9])?",因为一个数不能有尾随的零。实际上,源字符串可能已经被创建为一个固定位数的数字,例如:
printf("%.1f", x);

因此,它可能会以零字符轻松结束。当然,这些都是固定点表示法,而不是双精度本身。双精度数也可以写成-1.23e-4,而不是-0.000123。


09是一个有效的数字,允许有尾随零。例如9.45000是一个有效的数字。 - dannyhut
@dannyhut:这取决于情况。通常09和08不是有效的十进制数。前导零表示八进制表示法,前缀后允许的数字仅为0-7。 - ThatsMe
在小数点前面放置 0 是完全可以接受的。我们通常不这样做,因为这是不必要的,但是也没有问题。09 表示十位是 0,个位是 9。这也适用于数字指数后面的 0。许多编程语言(不仅仅是英语)都可以处理这种情况。例如,日期、电话号码、菜单中的价格以及任何需要填充的地方。 - dannyhut

20

这个正则表达式本身没有问题,问题出在你的转义上。你需要将 \ 字符进行双重转义,因为它也是 C++ 字符串转义字符。

另外还有一种情况,这个正则表达式会认为 1. 是一个有效的浮点数。所以你最好使用 /^[0-9]+(\\.[0-9]+)?$/,可以避免这种情况的发生。


5
也许不是直接的答案,但以下信息很有用。正则表达式:
std::regex rx(R"(^([+-]?(?:[[:d:]]+\.?|[[:d:]]*\.[[:d:]]+))(?:[Ee][+-]?[[:d:]]+)?$)");

匹配字符串:

"1", "0", "10",
"1000.1", "+1",
"+10", "-10", "1.",
".1", "1.1", "+1.",
"-1.", "+.1", "-.1",
"009", "+009", "-009",
"-01e0", "+01E0", "+1e-1",
"+1e+1", "+1.e1", "1E1",
"1E+1", "0.001e-12", "0.111111111111111"

并且不匹配下一个字符串:

".", "1a", "++1",
"+-1", "+", "-.",
"-", "--1.", "1.e.1",
"1e.1", "0+.e0"

这些值看起来像是C++中double类型的有效值,例如double test = +009.e+10是可以的。

在ideone.com上尝试运行:https://ideone.com/ooF8sG


4

/^[0-9]+.[0-9]+$ :使用此正则表达式来匹配双精度数。

可以接受123.123这样的数字类型。


4
应该使用 \. 作为小数点,否则会接受任何小数分隔符。 - 0x26res

3
/^[0-9]*[.]?[0-9]+$/

上述正则表达式适用于像“45.5”,“12”,“.12”这样的双精度数。


0
(\d+)?\.(\d+)?

上面的正则表达式适用于双精度浮点数,例如"45.5""12."".12"


它还接受单个句点字符,这绝对不是一个有效的数字。 - ThatsMe

0
    constexpr char double_regex_s[53] =
        "^" // accept only if it matches the beginning of the string
        "(-?)" // accept a single optional negation
        "(0|([1-9][0-9]*))" // number is either zero or some integer that does not start with zero
        "(" // begin optional decimals
            "\\." // require a dot
            "[0-9]+" // any digit is fine, but at least one (std::atof does not require but chrome requires digits after dot)
        ")?" // end optional decimals
        "(" // begin optional scientific exponent
            "[eE]" // require an e or E
            "[-+]?" // accept optional plus or minus
            "[0-9]+" // any digit is fine (tested in chrome JSON.parse(1E000003) works)
        ")?" // end optional scientific exponent
        "$" // accept only if it matches up to the end of the string
        ;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接