正则表达式(替换所有非数字字符并强制保留 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 decimal/period
- 虽然小数不是-必需的-.. 如果存在,请确保句点后只有 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;
}
});
最后更新:
(最终工作解决方案)...仍在检查下面发布的正则表达式解决方案...
- 没有逗号
- digits/numbers
之外没有字符
- 没有双'..'(点)
小数点后不超过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(糟糕)
我认为您对处理顺序没有意见。确保您正在重新使用 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,在本例中为通配符。
我目前正在研究一些正则表达式逻辑以强制字段输入仅接受 (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 decimal/period
- 虽然小数不是-必需的-.. 如果存在,请确保句点后只有 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;
}
});
最后更新:
(最终工作解决方案)...仍在检查下面发布的正则表达式解决方案...
- 没有逗号
- digits/numbers 之外没有字符
- 没有双'..'(点)
小数点后不超过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(糟糕)
我认为您对处理顺序没有意见。确保您正在重新使用 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,在本例中为通配符。