Quantico
Quantico

Reputation: 2436

jquery regex for numbers

I am trying to restrict my input field to numbers (they can be positive, negative and with a decimal point)

I did the following but this does not work as I want it

$(document).on('input', '[id^="original_invest"]', function(event) {
    var str = $(this).val();
    var patt = /\-?\d*\.?\d\d/g
    var result = str.match(patt);
    console.log(result);
});

First, it is always one char behind so if I type 5 and print result I see nothing and it is only matching after a certain amount of chars

So printing result for the following yields the following outputs 5 -> null 55 -> null 555 -> ["55"] 5555 -> ["555"]

what am I doing wrong?

Upvotes: 0

Views: 404

Answers (2)

h2ooooooo
h2ooooooo

Reputation: 39522

The problem is that \.?\d\d means "an optional . character followed by a digit followed by a digit". The last two digits are not optional so your regex will minimumly match 3 digits (as you can see 555 works).

You can use ^\-?\d+(\.\d+)?$ to match it instead.

Regex Autopsy:

  • ^ - The string has to start with the next match:
  • \-? - The literal character - matched 0 to 1 times
  • \d+ - A digit matched 1 to infinity times
  • (\.\d+)? - An optional regex group matching:
    • \. - A literal . character
    • \d+ - A digit matched 1 to infinity times
  • $ - The string must end with the previous match (do remember that it's optional though)

Regex101 demo

Note:

As you can see .33 is not considered a number. If you want this to work use \d* instead of \d+ in the first digit in the regex. This means "matched 0 to infinity times" rather than "1 to infinity".

Upvotes: 2

Ryan Wheale
Ryan Wheale

Reputation: 28380

You are almost there. You need to use the keyup event (as suggested in the comments above). keypress is the physical key being pushed, but the input value has not yet been updated. keyup is the physical key being released, and the input value has been updated.

Your regex needs some work:

  • I would require at least one digit: \d+
  • Since the decimal is optional, you should put that into it's own optional group: (\.\d{1,2})? - This allows a decimal followed by one or two digits. You can allow unlimited number of decimal digits by using (\.\d+)?
  • You should put boundary markers(^, $) to signify the beginning and end of the input, and get rid of the global /g flag

Here's the final:

/^\-?\d+(\.\d{1,2})?$/

Upvotes: 1

Related Questions