使用正则表达式验证货币时,IE 8崩溃

时间:2012-11-14 10:27:04

标签: jquery regex internet-explorer

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

所有这些在Firefox中完美运行。但是在IE 8中,在数字位数超过13之后,如果输入了一个字母,Internet Explorer就会挂起并崩溃!调试时我注意到它在正则表达式线上出错,但同样的正则表达式工作正常,直到没有超过13的限制! Regexperts,拜托!给我看灯!

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;
});

3 个答案:

答案 0 :(得分:5)

我很确定这是catastrophic backtracking的情况。你的正则表达式有太多的可能性来检查,直到它失败。

问题在于这部分

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

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

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

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

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

答案 1 :(得分:0)

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

function isIncorrectSpend(cubeCurrencySpend) {  
     return !/^(?!0)(?:\d[,\.]*){1,13}$/.test(cubeCurrencySpend);              
}

答案 2 :(得分: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()

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';
}

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