1

我已经编写了一堆代码来获得有效的支出金额条目(32.4554,234,324.34等)。我还编写了代码来限制用户输入超过 13 位数字(不包括.and ,)。

所有这些都在 Firefox 中完美运行。但是在 IE 8 中,位数超过 13 位后,如果输入一个字母,Internet Explorer 就会挂起并崩溃!在调试时,我注意到它在正则表达式行出现错误,但相同的正则表达式工作正常,直到没有超过 13 的限制!正则专家,请!给我看光!

function isIncorrectSpend(cubeCurrencySpend) {  
    if(!(/^([1-9]*[0-9]*,?[0-9]*)* (\.[0-9]*)?$/.test(cubeCurrencySpend))) {
        return true;
    }
    return false;
}

function isLongerThanThirteenDigits(cubeCurrencySpend) {
    cubeCurrencySpend = cubeCurrencySpend.replace(/,/g, "").replace(/\./g, "");
    if(cubeCurrencySpend.length>12) { 
        return true;
    }
    return false;
}

jQuery("input#minval").keyup( function() {
    if(isIncorrectSpend(jQuery("input#minval").val())) {
        jQuery("input#minval").val("");
        alert("please enter correct spend value");
    }        
});
jQuery("input#minval").keypress( function(e) {
    var code = (e.keyCode ? e.keyCode : e.which);
    if(isLongerThanThirteenDigits(jQuery("input#minval").val()) && (code > 47 && code < 58)) {
        alert("Please enter a number less than 13 digits");
        return false;
    }
    return true;
});
4

3 回答 3

5

我很确定这是一个灾难性的回溯。你的正则表达式有太多的可能性要检查,直到它失败。

问题是这部分

([1-9]*[0-9]*,?[0-9]*)*

而且我很确定它没有按照您的预期进行。

这将匹配相同的东西,但会失败得更快:

/^[1-9]*[0-9,]*(\.[0-9]+)?$/

它仍然允许像 1,,,,,,,.123 这样的东西,但比你的要好得多。如果你想禁止这样的事情,你需要澄清你的要求。

于 2012-11-14T10:59:42.133 回答
0

此答案假定您希望验证满足以下条件的十进制“数字”:

“数字”的定义

  • 必须至少有一位数字,并且所有数字都必须是十进制(从 0 到 9)。
  • 整数部分和小数部分都是可选的,但其中一个必须存在。
  • 小数部分(如果存在)可以有任意位数,但总是以小数点开头。
  • 如果整数部分多于一位,则前导数字不得为零。
  • 如果整数部分多于三位数,可以使用逗号将整数分隔为数字三元组。
  • 数字可以以可选符号开头,加号+或减号-
  • 不允许使用空格。
  • 不允许使用指数部分。

鉴于上述要求,这里有一些有效和无效的数字

有效的“数字”:

0
0.
.0
0.0
1
+1
-1
1234
123456
1,234
12,345
123,456
123,456.7890

无效的“数字”:

0FA92      // Invalid digit. Must be 0-9.
0123       // Multi-digit integer must lead with non-zero.
.          // Must have at least one digit.
1,23,4     // Commas must separate triplets of digits.
12345,678. // Missing comma.
+  10      // Whitespace not allowed.
1.2E34     // Exponents not allowed.

这是一个正则表达式(首先使用 Python 方便的原始字符串语法以注释、自由间距模式格式呈现)匹配满足上述要求的数字:

正则表达式验证“数字”

r"""
^          # Anchor to start of string.
[+\-]?     # Optional sign.
(?=\.?\d)  # Must have at least one digit.
(?:        # Optional integer part. Either...
  [1-9]    # A sequence of digits w/no commas.
  \d*      # (but first digit is not zero.)
|          # or an integer having commas...
  [1-9]    # First digit is not zero.
  \d{0,2}  # 1,2 or 3 digits ahead of 1st comma.
  (?:      # One or more comma + 3 digits.
    ,      # Comma separates
    \d{3}  # digit triplets.
  )+       # One or more comma + 3 digits.
| 0        # or integer part may be just zero.
)?         # Optional integer part.
(?:        # Optional fractional part.
  \.       # Dot separates
  \d*      # zero or more fraction digits.
)?         # Optional fractional part.
$          # Anchor to end of string.
"""

这是一个实现上述正则表达式的 JavaScript 函数:

函数是有效数字()

function isValidNumber(text) {
    var re = /^[+\-]?(?=\.?\d)(?:[1-9]\d*|[1-9]\d{0,2}(?:,\d{3})+|0)?(?:\.\d*)?$/;
    if((re.test(text))) return 'true';
    return 'false';
}

请注意,在用户完成输入整个号码之前,您不应该尝试验证号码。为每个按键调用验证函数(正如您上面的代码似乎正在做的那样)恕我直言,这不是一个好的做法。

于 2012-11-14T18:10:08.483 回答
0

您还可以更改正则表达式以结合长度和有效性检查。

function isIncorrectSpend(cubeCurrencySpend) {  
     return !/^(?!0)(?:\d[,\.]*){1,13}$/.test(cubeCurrencySpend);              
}
于 2012-11-14T11:08:06.613 回答