RegEx(替换所有非数字字符和2个小数点后的数字)

时间:2019-02-19 16:04:14

标签: javascript jquery regex validation currency

我目前正在研究一些正则表达式逻辑,以强制字段输入仅接受(替换/显示)数字(无字母字符)并强制使用小数点后2位...

我不确定如何提高效率,还要添加(最大)2个小数位限制/限制?

这是我当前使用的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
    }   
});

我最初使用的是它,但它是错误的(如果您回去并在当前/现有数字中添加逗号,则会删除该字段中的最后一个数字/字符。.(即使这不是冒犯的字符)

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个小数/句号
  • 使用小数表示-不需要-..如果存在,请确保句点后仅保留小数点后2位

更新1:

好..所以我有“关闭”的东西(尽管REGEX的一行很不错!)

我的最后一个“待办事项” ..是要以某种方式强制执行(如果有一个“点” ...,它后面仅保留2个小数位.....尽管点/小数是-not -必填)

$("#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;

    }

});

更新最终版本:
(最终可行的解决方案)...仍在检查下面发布的正则表达式解决方案...

  • 没有逗号
  • 没有数字/数字以外的字符
  • 没有双'..'(点)
  • 小数点后不能超过2位数字

    $("#amount").on("keyup", function(){                            
        var valid = /^\d{0,9}(\.\d{0,2})?$/.test(this.value);
    val = this.value;
    
    if(!valid){
        var dotCheck = val.indexOf("..");
        if(dotCheck >= 0){                              
            val = val.replace("..", ".");
        }
    
        //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;                           
    }
    
    
    });
    

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

1.9.9(炸弹)

3 个答案:

答案 0 :(得分:1)

这是您最终编辑的修改版本...我添加了一行以检查情况:1.2.3并用图案替换它以除去第二个点。是否做到了不留痕迹,因为它可能不受支持。这是一行:val = val.replace(/(\.)(.)(\.)/g, ".$2"); ".$2"将替换。#。在这种情况下,带有点和模式组(即通配符(。))。您底部的其他支票将出现双点“ ..”情况。

$("#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, ".$2");

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

编辑:通过添加括号来修复新行。说明:括号将模式的各个部分“分组”在一起(基于1的索引)。因此,新行有3个组-(\.)- 1, (.)- 2, (\.)- 3。替换为$2将呼叫组#2,在本例中为通配符。

答案 1 :(得分:0)

我认为您可以接受处理订单。确保您正在重新使用val变量。上面的代码将val设置为等于this.value,但是在每个模式之后,您都将替换设置为this.value,而不是重新使用val。您只会看到上次替换呼叫的结果。

您可以找到任何非数字字符的模式。唯一的效率可能是使用逻辑OR(|)将其与逗号检查结合起来,例如:\d{0,9}(\.\d{0,2})?|,

关于强制使用小数点后两位,您可以使用类似以下的命令:(?<=\.[0-9]{2}).+。这是积极的看法:(?<= PATTERN ),并将返回后面带有该模式的匹配项。以下是细分:

  • (?<=-开始积极回望
  • \.[0-9]{2}-将小数点('。')后面跟两个数字匹配
  • )-积极回望的终结
  • .+-后看模式之后的所有内容

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

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

答案 2 :(得分:0)

尝试:^(\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'