-1

I have

const int = /^[-+]?[1-9]+/
const float = /[+-]?([0-9]*[.])?[0-9]+/

// float return true for 

float.exec(1234)

// int return true for
// it matches only 4848
int.exec(4848.48)

How do I match only integers and only floats with the respective regex?

buddemat
  • 4,552
  • 14
  • 29
  • 49
Phoxett
  • 95
  • 6

1 Answers1

1

Add start ^ and end $ delimiters to your expression that matches integers, so that it cannot match only part of a floating point number (see this regex101):

^[-+]?[0-9]+$

Please note that your original expression for integers wouldn't match integers with zeros in them.

In the floating point case, do the same and also move the point so that it becomes non optional (see this regex101). To match a literal point, you can also escape it instead of using a character group, so that it's not . which would mean "any character":

^[+-]?[0-9]*\.[0-9]+$

Note that this will match:

  • leading zeros, e.g. 001, 00.2
  • floats with trailing zeros, e.g. 0.200000000
  • an explicit plus sign, +123, +1.2, +.2
  • signed zeros: -0 and +0 respectively +0.0 and -0.0

If you don't want leading zeros, you can distinguish that with an or (|). For integers (see regex101):

^[-+]?(?:0|[1-9][0-9]*)$

For floats, you need to make the non-capturing group optional, so that numbers that start with a literal dot are still valid (see regex101):

^[+-]?(?:0|[1-9][0-9]*)?\.[0-9]+$

If you want to exclude signed zeros, which depending on who you ask exist or don't exist in math, but are assignable in most programming languages, you can move the optional sign into the second condition of the or. For integers (see regex101):

^(?:0|[-+]?[1-9][0-9]*)$

For floats, this is more tricky. If you again move the sign into the second condition of the or, you won't match +0.0 and -0.0, but you also won't match signed numbers that start with a literal point or 0., so this will not work (see regex101).

To remedy this, you can wrap the whole thing in another or and add a negative lookahead in the second condition to explicitly distinguish between 0.0 and others starting with 0. (see regex101):

^(?:0\.0*|[+-]?(?:(?!0\.0*$)0|[1-9][0-9]*)?\.[0-9]+)$

Finally, if you want to assert that the number does not end with trailing zeros, add an appropriate negative lookbehind (?<![0-9]0) at the very end after the line ending $ (see regex101):

^(?:0\.0*|[+-]?(?:(?!0\.0*$)0|[1-9][0-9]*)?\.[0-9]+)$(?<![0-9]0)

Btw, you can also use \d instead of [0-9].

Note that in javascript, the exec() call may not match for floating point arguments that evaluate to 0, because that happens before the evaluation of the exec() (see jsfiddle):

const float = /^[+-]?(?:0|[1-9]\d*)?\.\d+$/ // floats with no leading zeros

console.log(float.exec(0.0))      // null
console.log(float.exec(0.0000))   // null
console.log(float.exec(+0.0))     // null
console.log(float.exec(-0.0))     // null
console.log(float.exec('0.0'))    // ["0.0"]
console.log(float.exec('0.0000')) // ["0.0000"]
console.log(float.exec('+0.0'))   // ["+0.0"]
console.log(float.exec('-0.0'))   // ["-0.0"]
buddemat
  • 4,552
  • 14
  • 29
  • 49