Skip to content

Need a RegExp to filter out all but one decimal point

I’m using the following code to negate the characters in the regexp. By checking the inverse, I can determine if the value entered is correctly formatted. Essentially, any digit can be allowed but only one decimal point (placed anywhere in the string.) The way I have it now, it catches all numerals, but allows for multiple decimal points (creating invalid floats.) How can I adjust this to catch more than one decimal points (since I only want to allow for one)?

var regex = new RegExp(/[^0-9.]/g);
    var containsNonNumeric = this.value.match(regex);
    if(containsNonNumeric){
        this.value = this.value.replace(regex,'');
        return false;
    }

Here is what I’m expecting to happen:

First, valid input would be any number of numerals with the possibility of only one decimal point. The current behavior: The user enters characters one by one, if they are valid characters they will show up. If the character is invalid (e.g. the letter A) the field will replace that character with ”(essentially behaving like a backspace immediately after filling the character in. What I need is the same behavior for the addition of one too many decimal points.

Answer

As I understand your question the code below might be what you are looking for:

var validatedStr=str.replace(/[^0-9.]|.(?=.*.)/g, "");

It replaces all characters other then numbers and dot (.), then it replaces all dots followed by any number of 0-9 characters followed by dot.


EDIT based on first comment – the solution above erases all dots but the last, the author wants to erase all but the first one: Since JS does not support “look behind”, the solution might be to reverse string before regex, then reverse it again or to use this regex:

var counter=0;
var validatedStr=str.replace(/[^0-9.]|./g, function($0){
    if( $0 == "." && !(counter++) ) // dot found and counter is not incremented
        return "."; // that means we met first dot and we want to keep it
    return ""; // if we find anything else, let's erase it
});

JFTR: counter++ only executes if the first part of condition is true, so it works even for strings beginning with letters