简体   繁体   中英

Remove Any Non-Digit And Check if Formatted as Valid Number

I'm trying to figure out a regex pattern that allows a string but removes anything that is not a digit, a . , or a leading - .

I am looking for the simplest way of removing any non "number" variables from a string. This solution doesn't have to be regex.

This means that it should turn

1.203.00 -> 1.20300
-1.203.00 -> -1.20300
-1.-1 -> -1.1
.1 -> .1
3.h3 -> 3.3
4h.34 -> 4.34
44 -> 44
4h -> 4

The rule would be that the first period is a decimal point, and every following one should be removed. There should only be one minus sign in the string and it should be at the front.

I was thinking there should be a regex for it, but I just can't wrap my head around it. Most regex solutions I have figured out allow the second decimal point to remain in place.

You can use this replace approach:

  • In the first replace we are removing all non-digit and non-DOT characters. Only exception is first hyphen that we negative using a lookahead.
  • In the second replace with a callback we are removing all the DOT after first DOT.

Code & Demo:

 var nums = ['..1', '1..1', '1.203.00', '-1.203.00', '-1.-1', '.1', '3.h3', '4h.34', '4.34', '44', '4h' ] document.writeln("<pre>") for (i = 0; i < nums.length; i++) document.writeln(nums[i] + " => " + nums[i].replace(/(?!^-)[^\\d.]+/g, ""). replace(/^(-?\\d*\\.\\d*)([\\d.]+)$/, function($0, $1, $2) { return $1 + $2.replace(/[.]+/g, ''); })) document.writeln("</pre>") 

I can do it with a regex search-and-replace. num is the string passed in.

num.replace(/[^\d\-\.]/g, '').replace(/(.)-/g, '$1').replace(/\.(\d*\.)*/, function(s) {
  return '.' + s.replace(/\./g, '');
});

A non-regex solution, implementing a trivial single-pass parser. Uses ES5 Array features because I like them, but will work just as well with a for-loop.

 function generousParse(input) { var sign = false, point = false; return input.split('').filter(function(char) { if (char.match(/[0-9]/)) { return sign = true; } else if (!sign && char === '-') { return sign = true; } else if (!point && char === '.') { return point = sign = true; } else { return false; } }).join(''); } var inputs = ['1.203.00', '-1.203.00', '-1.-1', '.1', '3.h3', '4h.34', '4.34', '4h.-34', '44', '4h', '.-1', '1..1']; console.log(inputs.map(generousParse)); 

Yes, it's longer than multiple regex replaces, but it's much easier to understand and see that it's correct.

OK weak attempt but seems fine..

 var r = /^-?\\.?\\d+\\.?|(?=[az]).*|\\d+/g, str = "1.203.00\\n-1.203.00\\n-1.-1\\n.1\\n3.h3\\n4h.34\\n44\\n4h" sar = str.split("\\n").map(s=> s.match(r).join("").replace(/[az]/,"")); console.log(sar); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM