正则表达式(替换所有非数字字符并强制保留 2 个小数位数字)

RegEx (replace all non numeric characters and enfore 2 decimal place numbers)

我目前正在研究一些正则表达式逻辑以强制字段输入仅接受 (replace/display) 数字(无字母字符)并强制执行小数点后两位限制...

我不确定如何才能提高效率,并添加(最多)2 位小数 limit/restriction?

这是我当前的 keyup() 函数

$("#amount").on("keyup", function(){

    var valid = /^\d{0,9}(\.\d{0,2})?$/.test(this.value);
    val = this.value;

    if(!valid){
        console.log('bad character found');

        //strip out commas
        this.value = val.replace(/,/g , "");

        //strip out all non-numeric characters (leaving decimal)
        //this.value = val.replace(/[^\d.-]/g, "");
        this.value = val.replace(/[^0-9.]/g, "");

        //enforce only (max) 2 decimal places
    }   
});

我最初使用的是这个,但它有缺陷(如果你返回并在 current/existing 数字中添加一个逗号,它会删除该字段中的最后一个 digit/character..(甚至虽然那不是冒犯性的角色)

var valid = /^\d{0,9}(\.\d{0,2})?$/.test(this.value);
val = this.value;

if(!valid){
    //console.log("Invalid input!");
    this.value = val.substring(0, val.length - 1);
}

说清楚...

该值不必有小数点,并强制在所述小数点后保留 2 位数字。但如果有的话。我需要在小数点后强制执行 2 个字符的限制。

更新 1:

好的..所以我有东西'close'(尽管一行REGEX会很好!)

我最后的 'to-do' 项目.. 是以某种方式强制执行(如果有 'dot'... 它后面只有 2 位小数..... 虽然 dot/decimal 不是必需的)

$("#amount").on("keyup", function(){
    var valid = /^\d{0,9}(\.\d{0,2})?$/.test(this.value);
    val = this.value;
    console.log("ORIGINAL VAL: " + val);

    if(!valid){
        console.log('bad character found');

        var dotCheck = val.indexOf("..");
        if(dotCheck >= 0){
            console.log('DOT CHECK: ' + dotCheck);
            console.log("PRE VAL: " + val);
            val = val.replace("..", "?");
            console.log("POST VAL: " + val);
        }       

        //strip out commas                      
        val = val.replace(/,/g , "");                           
        console.log("AFTER COMMA VAL: " + val);

        //strip out all non-numeric characters (leaving decimal)
        val = val.replace(/[^0-9.]/g, "");
        console.log("AFTER CHAR VAL: " + val);

        //output to field
        this.value = val;

    }

});

最后更新:
(最终工作解决方案)...仍在检查下面发布的正则表达式解决方案...

编辑:我发现这不能处理像 L

这样的事情

1.9.9(糟糕)

我认为您对处理顺序没有意见。确保您正在重新使用 val 变量。上面的代码会将 val 设置为 this.value,但是在每个模式之后,您将替换设置为 this.value 而不是重新使用 val。您只会看到上次调用替换的结果。

您查找任何非数字字符的模式都很好。唯一的效率可能是通过使用逻辑或 (|) 将其与逗号检查结合起来,如下所示:\d{0,9}(\.\d{0,2})?|,.

至于强制两位小数,你可以使用这样的东西:(?<=\.[0-9]{2}).+。这是背后的正面看法:(?<= PATTERN ) 和 will return 匹配背后有该模式的匹配项。这是细分:

  • (?<= - 正面观察开始
  • \.[0-9]{2} - 匹配一个十进制字符 ('.') 及其后的 2 个数字
  • ) - 正面观察结束
  • .+ - 后视模式
  • 之后的任何内容

您可以使用它来替换空白字符串,就像您使用其他模式一样。如果点后只有一位小数(例如:123.4),则不会被替换,因为“.4”与后面的正数不匹配。类似于:this.value = this.value.replace(/(?<=\.[0-9]{2}).+/g, "");

** 注意:在 https://regexr.com/ 上测试过模式,但在 js 代码

上没有测试过

尝试:^(\d+)(\.\d{2})?$

s ='1234567'
/^(\d+)(\.\d{2})?$/.test(s)
// true

s ='12345.67'
/^(\d+)(\.\d{2})?$/.test(s)
// true

s ='12345.678'
/^(\d+)(\.\d{2})?$/.test(s)
// false

s ='123.45.67'
/^(\d+)(\.\d{2})?$/.test(s)
// false

s ='a12345.67'
/^(\d+)(\.\d{2})?$/.test(s)
// false

更新: 正则表达式替换多个'.'字符

s = '123...45'
s.replace(/(\.)+/g, '.')
// '123.45'

这是您最终编辑的修改版本...我添加了一行来检查情况:1.2.3 并将其替换为删除第二个点的模式。没有回头看,因为它可能不受支持。这是行: val = val.replace(/(\.)(.)(\.)/g, "."); "." 将替换 .#。带有点和模式组,在本例中为通配符 (.)。您在底部的另一张支票会出现双点“..”的情况。

$("#amount").on("keyup", function () {
    var valid = /^\d{0,9}(\.\d{0,2})?$/.test(this.value);
    val = this.value;
    console.log("ORIGINAL VAL: " + val);

    if (!valid) {
        var dotCheck = val.indexOf("..");
        if (dotCheck >= 0) {
            val = val.replace("..", ".");
        }

        val = val.replace(/(\.)(.)(\.)/g, ".");

        //strip out commas                                          
        val = val.replace(/,/g, "");

        //strip out all non-numeric characters (leaving decimal)                            
        val = val.replace(/[^0-9.]/g, "");

        //enforce 2 decimal places (max)                    
        var totalLength = val.length;
        var only2DecimalsCount = val.indexOf(".");

        if (only2DecimalsCount >= 0 && totalLength > (only2DecimalsCount + 2)) {
            val = val.substring(0, (only2DecimalsCount + 3));
        }

        //output to field
        this.value = val;
    }
});

编辑: 通过添加括号修复新行。解释:括号 "groups" 模式的碎片在一起(基于 1 的索引)。所以新线有 3 组 - (\.)- 1, (.)- 2, (\.)- 3。替换为 将调用组 #2,在本例中为通配符。