1

I have a regular expression in a code(written by someone else), I am trying to understand what that expression means.

var decimal = /^\d[0,1]+(\.\d[1,4])?$/;

Can anyone explain to me what it does...

Patrick Hofman
  • 148,824
  • 21
  • 237
  • 306
dilettante_aficionado
  • 1,214
  • 2
  • 25
  • 45

2 Answers2

4

In order:

  • ^ - Match the beginning of the input

  • \d - A digit (0-9)

  • [0,1]+ - One or more occurrences of the characters 0, ,, or 1 —but see note below, this is probably not what the author meant to do

  • ( - The beginning of a capture group

  • \. - A literal . (without the backslash, it would mean something special)

  • \d - A digit

  • [1,4] - Exactly one of the characters 1, ,, or 4 —but see note below, this is probably not what the author meant to do

  • ) - The end of the capture group

  • ? - Inidicates that the entire capture gruop is optional (zero or once)

  • $ - Match the end of the input

Re the [0,1]+ and [1,4], the expression was probably supposed to have {0,1} and {1,4} instead, which mean:

  • {0,1} - match what came before either zero times or once (note that you have to remove the + that was after the [0,1])

  • {1,4} - match what came before 1, 2, 3, or 4 times

Here's an explanation on regex101.com

If we speculate that they probably meant this

/^\d{0,1}(\.\d{1,4})?$/

...then in prose it means: Match any number that may or may not have one leading digit, and then may or may not have a decimal point followed by one to four digits. But it's still got issues, not least that the string "" matches it, and (depending on what you're doing) you probably want to support values equal to or greater than 2, which that expression doesn't.

Basically: If it's meant to validate a decimal, throw it away, and search for something that does a better job, such as this if you really want at most four digits of precision and you want to capture the fractional portion (as your original does):

/^(?:0|[1-9]\d*)(\.\d{1,4})?$/

If you want to allow any level of precision:

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

If you don't need the capture group:

/^(?:0|[1-9]\d*)(?:\.\d{1,4})?$/     // Only allow 1-4 digits of precision
/^(?:0|[1-9]\d*)(?:\.\d+)?$/         // Allow any number of digits of precision

That last is probably what I'd go with. Note that it doesn't allow leading zeros you wouldn't normally write (e.g., it disallows 02.345). If you want to allow them, then just /^\d*(?:\.\d+)?$/.

T.J. Crowder
  • 959,406
  • 173
  • 1,780
  • 1,769
  • i think the author meant to validate only decimal values, that numbers, i.e. the number can be either a natural number or a decimal but a number. . so is it working it that way..?? – dilettante_aficionado Dec 16 '14 at 14:35
  • @kkk: No, not remotely; see above. If you just want to validate a number that can be `0`, `27`, `0.143`, `241.33432`, you want one of the last batch of regexes above (probably; they're a bit off-the-cuff, but...). – T.J. Crowder Dec 16 '14 at 14:36
2

The crucial parts:

^: Beginning of input

\d: A digit

[0,1]+: One or more occurences of 0 or 1 or ,

(\.\d[1,4])?: An optional capture group, containing: a . literal, a digit, and a 1 or 4 or ,

$: End of input

The full story can be found here.

So some allowed input is:

  • 80.94
  • 41111111.44
  • 4,,,1.44
  • 30
Patrick Hofman
  • 148,824
  • 21
  • 237
  • 306