这适用于整数,例如:
'123x'.replace(/\D/g, '')
'123'
以下正则表达式可以实现相同的功能,但只允许一个小数点:
^(\d+\.?\d*)$
示例:
1
->1
1x
->1
10.
->10.
10.0
->10.0
10.01
->10.01
10.01x
->10.01
10.01.
->10.01
这适用于整数,例如:
'123x'.replace(/\D/g, '')
'123'
以下正则表达式可以实现相同的功能,但只允许一个小数点:
^(\d+\.?\d*)$
示例:
1
-> 1
1x
-> 1
10.
-> 10.
10.0
-> 10.0
10.01
-> 10.01
10.01x
-> 10.01
10.01.
-> 10.01
使用两个替换:
console.log("a12b3.1&23.0a2x".replace(/[^.\d]/g, '')
.replace(/^(\d*\.?)|(\d*)\.?/g, "$1$2"));
第一个操作会删除除数字和点以外的所有字符。
第二个替换匹配数字序列,可能后跟一个点,但有两种不同的方式。当该序列出现在字符串开头时,可选的点被放在第一个捕获组内,而对于所有其他匹配,点位于第二个捕获组之外。
有两个捕获组,但对于任何给定的匹配,只有其中一个会实际包含内容。因此,可以使用$1$2
在任一情况下重现捕获的内容。这将包括第一个点,但不包括任何其他点。
parseFloat
并转换回字符串,即可实现。最初的回答中已经提到了这一点。
console.log(parseFloat('10.01.x').toString());
使用正则表达式的一种方法。
function convert(s) {
return s.match(/^\d+\.?\d*/)[0];
}
console.log(['1', '1x', '10.', '10.0', '10.01', '10.01x', '10.01.'].map(convert));
更新
为什么不采用老派的方式:
function formatNumber(s) {
var hadDot = false, result = '';
for (var i = 0; i < s.length; i++) {
var c = s[i];
if (c >= '0' && c <= '9')
result += c;
else if (!hadDot && c == '.') {
hadDot = true;
result += c;
}
}
return result;
}
var inputs = ['10.01.x23.5asd6', '10.', '10', '.12vx12.1f53', '10.10.'];
for (var i = 0; i < inputs.length; i++) {
console.log(formatNumber(inputs[i]));
}
只需要对字符串进行一次迭代,因此您可能不会得到更好的运行时间。
旧答案,不起作用
这个也应该可以工作(但它没有,感谢trincot指出):
function formatNumber(s) {
return s.replace(/[^\d\.]/g, '').replace(/\.(([^\.]*)\.)*/g, '.$2');
}
var inputs = ['10.01.x23.5asd6', '10.', '10', '.12vx12.1f53', '10.10.'];
for (var i = 0; i < inputs.length; i++) {
console.log(formatNumber(inputs[i]));
}
\.([.\d]+)$
来匹配第一个点后的整个字符串(包括点),并在回调中从捕获的值(第一个点后的字符串)中删除所有剩余的点。'123x'.replace(/[^\d.]/g, '').replace(/\.([.\d]+)$/,function(m,m1){
return '.' + m1.replace(/\./g, '')
})
演示:
var arr = ['1', '1x', '10.', '10.0', '10.01', '10.01x', '10.01.', '10.01.23', 'a1b2c3d.e4f5g6h'];
function format(str) {
return str.replace(/[^\d.]/g, '').replace(/\.([.\d]+)$/, function(m, m1) {
return '.' + m1.replace(/\./g, '')
});
}
arr.forEach((v) => console.log(`${v} => ${format(v)}`))
如果你想要除了数字以外的所有东西都删除,而且只保留第一个点的出现,那么这将是一个很好而简单的解决方案。
"ab12..34..c".replace(".", "~").replace(/[^0-9~]/g, "").replace("~", ".")
输出:12.34
第一次替换:将第一个点(.)替换为波浪号(~)。 第二次替换:仅保留数字和波浪号(只有一个)。 第三次替换:将波浪号替换为点。
let arr = ['1', '1x', '10.', '10.0', '10.01', '10.01x', '10.01.', '10.01.23', 'a1b2c3d.e4f5g6h'];
arr.forEach(val => {
val = val.replace(/[^\d.]/g, '').match(/([0-9]+(\.[0-9]*)?)/);
if (val) console.log(val[0]);
})
replace(/[^\d.]/g, '')
用于替换任何非数字字符和非 .
字符。
[0-9]+
匹配从0到9的数字,+
表示匹配一次或多次。
.
后面跟着一个点。
[0-9]*?
匹配从0到9的数字(但可以匹配零次或多次)。