Javascript:替换数字以外的所有内容,只允许一个点

时间:2019-03-15 19:15:00

标签: javascript ecmascript-6

这适用于整数,例如:

'123x'.replace(/\D/g, '')
'123'

哪个正则表达式可以实现相同的功能,但是只允许一个点?例子:

  • 1-> 1
  • 1x-> 1
  • 10.-> 10.
  • 10.0-> 10.0
  • 10.01-> 10.01
  • 10.01x-> 10.01
  • 10.01.-> 10.01

5 个答案:

答案 0 :(得分:3)

有两个替换项:

console.log("a12b3.1&23.0a2x".replace(/[^.\d]/g, '')
                             .replace(/^(\d*\.?)|(\d*)\.?/g, "$1$2"));

第一个操作将删除数字和点以外的所有字符

第二个替换匹配可能跟有一个点的数字序列,但是它以两种不同的方式匹配。当这样的序列出现在字符串的开头时,可选点放在第一个捕获组的 inside 中,而对于所有其他匹配项,该点位于第二个捕获的 outside 外捕获组。

有两个捕获组,但是对于任何给定的匹配,实际上只有其中一个具有内容。因此,无论哪种情况,都可以使用$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));

答案 2 :(得分:1)

您可以执行以下操作,需要两种替换方法:

  1. 用于除去数字和点以外的所有内容。为此,使用否定的字符类`[^ \ d。]。
  2. 要删除重复的点,请使用replace with callback,其中我们需要替换第一个点之后的内容,因此请使用\.([.\d]+)$来匹配第一个do之后的整个字符串(包括点),并在回调中从中删除所有剩余的点捕获的值(第一个点之后的字符串)。

'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)}`))

答案 3 :(得分:1)

更新

为什么不简单地做旧学校:

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

首先,替换所有非数字和点。然后,捕获第一个点之后的所有内容,并将其替换为非点的任何内容。但是,它需要两步正则表达式。

答案 4 :(得分:0)

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的数字将匹配,+代表match one or more time

.后跟一个点。

[0-9]*?从0到9匹配(但匹配零个或多个时间)