匹配最多包含两位小数的数字的正则表达式

12

我需要一个正则表达式,能匹配带有最多用户定义的小数位数的数字值。目前我已经有了以下正则表达式:

/(^-?\d\d*\.\d*$)|(^-?\d\d*$)|(^-?\.\d\d*$)/

我想要允许与输入相同数量的地方,但有时我还想允许货币输入两个或其他输入四个或更多。 我正在构建的函数是:

var isNumeric = function(val, decimals) {
    // decimals is not used yet
    var objRegExp = /(^-?\d\d*\.\d*$)|(^-?\d\d*$)|(^-?\.\d\d*$)/;
    return objRegExp.test(val);
};
8个回答

24
/^\s*-?[1-9]\d*(\.\d{1,2})?\s*$/

忽略空格 (\s) 是一个好习惯。上面的代码不允许以零开头。如果你想允许这样:

/^\s*-?\d+(\.\d{1,2})?\s*$/

以上两种方法都不允许小数点前面没有数字的小数。如果您想允许这种情况:

/^\s*-?(\d+(\.\d{1,2})?|\.\d{1,2})\s*$/

你是否有一种变量允许在末尾加上 . 而不跟任何数字?JavaScript 认为这是一个有效的数字,只要没有两个点在末尾 (isNaN(1.) //false)。 - Jacob Stamm

10
尝试使用以下内容:

^\d+\.\d{0,3}$

其中“3”表示允许的最大小数位数。


根据MDN(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#quantifiers)的说法,量词`x{n,m}`要求“n和m是**正整数**”-即0不是有效的下限。但是规范(https://www.ecma-international.org/ecma-262/5.1/#sec-15.10.1)指出,`n`和`m`的类型是`DecimalDigits`,因此允许使用0。MDN在这里是错误的:您的表达式符合规范,并且可以在任何浏览器中安全使用。 - hashchange

4

如果最后一位是".",加上0并不能解决点后有空格的情况。

我认为这样就涵盖了所有的情况,但你需要进行更严密的测试来验证。

var isNumeric = function(val, decimals) {
    if (decimals <= 0) {
        var re = /^\s*\d+\.?\s*$/;
        return re.test(val);
    } else {
        var reString = "^\\s*((\\d+(\\.\\d{0," + decimals + "})?)|((\\d*(\\.\\d{1," + decimals + "}))))\\s*$"
        var re = new RegExp(reString);
        return re.test(val);
    }
};

var test = function(val, decimals) {
    document.write("isNumeric(" + val + ", " + decimals + ") = " + isNumeric(val, decimals) + "<br/>");
}

test("123", 0);
test("123", 5);
test(" 123.45", 2);
test(" 123.45", 3);
test(" 123.45", 1);
test(" ", 0);
test(" ", 5);
test(" 3.", 0);
test(" 3.", 12);
test(" .", 3);
test(" .321 ", 5);

3
感谢大家的帮助。我结合了所有答案的部分内容。
var isNumeric = function(val, decimalPlaces) {
    // If the last digit is a . then add a 0 before testing so if they type 25. it will be accepted
    var lastChar = val.substring(val.length - 1);
    if (lastChar == ".") val = val + "0";

    var objRegExp = new RegExp("^\\s*-?(\\d+(\\.\\d{1," + decimalPlaces + "})?|\\.\\d{1," + decimalPlaces + "})\\s*$", "g");
    if (decimalPlaces == -1)
        objRegExp = new RegExp("^\\s*-?(\\d+(\\.\\d{1,25})?|\\.\\d{1,25})\\s*$", "g");

    return objRegExp.test(val);        
};

3

我是一名C#开发者,但我发现像The Regulator这样的工具对于调整正则表达式非常有帮助。同样,RegexPal也是一个非常实用的工具。


2

试试这个正则表达式,它对我来说很有效:

^\d+\.\d{0,2}$

1

这应该匹配整数和小数,最多两位小数。

/\A[+-]?\d+(?:\.\d{1,2})?\z/

注意: 将“{1,2}”中的“2”更改为您想支持的小数位数。

我知道这不是你问题的一部分,但你也可以不使用正则表达式来完成。以下是一种解决方案:

var isNumeric = function( val, decimals ) {
    if ( parseFloat( val ) ) {
        var numeric_string = val + '';
        var parts = numeric_string.split( '.', 1 );
        if ( parts[1] && parts[1].length > decimals ) {
            alert( 'too many decimal places' );
        }
        else {
            alert( 'this works' );
        }
    }
    else {
        alert( 'not a float' );
    }
}

使用以下语法,无法匹配整数或小数点后一到两位的数字:var regex = new Regex("/\A[+-]?\d+(?:\.\d{1,2})?\z/"); if (regex.IsMatch("1234")) { - beyond-code

1
使用这个模式:
[0-9]?[0-9]?(\.[0-9][0-9]?)? 

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