Sri
Sri

Reputation: 59

Javascript Regular expression for basic digits with decimal points?

I am trying to use a regular expression to validate decimal values . I wrote below regular expression but it does not allowing first decimal with value like a .5 or .6 or .1

Regular Exp : /^\d[0-9]{0,13}(\.\d{1,2})?$/

Rules :

  1. It should allow positive numbers.
  2. It should allow max 13 numbers before decimal point
  3. It should allow max two number after decimal.
  4. It should allow .(dot) with number like a .5
  5. It should not allow the .0

Example - Valid inputs

Example - invalid inputs

const valid = [
  "0",
  "0.5",
  "1.55",
  ".5",
  "1234567890123",
  "1234567890123.5",
  "1234567890123.00",
];

const invalid = [
  ".",
  ".0",
  "1.234",
  "5.",
  "12345678901234",
  "12345678901234.56",
];

const rgx = /^\d[0-9]{0,13}(\.\d{1,2})?$/

console.log("Checking valid strings (should all be true):");
valid.forEach(str => console.log(rgx.test(str), str));

console.log("\nChecking invalid strings (should all be false):");
invalid.forEach(str => console.log(rgx.test(str), str));

Upvotes: 5

Views: 165

Answers (4)

The fourth bird
The fourth bird

Reputation: 163207

To match your values you could use a non capturing group with an alternation using | and specify what you want to match.

^(?:\.[1-9][0-9]?|\d{1,13}(?:\.\d{1,2})?|.\d{2})$

This will also match .01 and not .0

Explanation

  • ^ Begin of the string
  • (?: Non capturing group
    • \.[1-9][0-9]? Match dot not followed by a 0 and then 0-9
    • | Or
    • \d{1,13} Match 1 - 13 digits
    • (?: Non capturing group
      • \.\d{1,2} Match a dot and 1 or 2 digits
    • )? Close non capturing group and make it optional
    • | Or
    • .\d{2} Match dot followed by 2 digits
  • ) Close non capturing group
  • $ End of the string

const valid = [
  "0",
  ".01",
  "0.5",
  "1.55",
  ".5",
  "1234567890123",
  "1234567890123.5",
  "1234567890123.00",
];

const invalid = [
  ".",
  ".0",
  "1.234",
  "5.",
  "12345678901234",
  "12345678901234.56",
];

const rgx = /^(?:\.[1-9][0-9]?|\d{1,13}(?:\.\d{1,2})?|.\d{2})$/;

console.log("Checking valid strings (should all be true):");
valid.forEach(str => console.log(rgx.test(str), str));

console.log("\nChecking invalid strings (should all be false):");
invalid.forEach(str => console.log(rgx.test(str), str));

To not match .01 you could use:

^(?:\d{1,13}(?:\.\d{1,2})?|\.[1-9][0-9]?)$

const valid = [
  "0",
  "0.5",
  "1.55",
  ".5",
  "1234567890123",
  "1234567890123.5",
  "1234567890123.00",
];

const invalid = [
  ".",
  ".0",
  ".01",
  "1.234",
  "5.",
  "12345678901234",
  "12345678901234.56",
];

const rgx = /^(?:\d{1,13}(?:\.\d{1,2})?|\.[1-9][0-9]?)$/;

console.log("Checking valid strings (should all be true):");
valid.forEach(str => console.log(rgx.test(str), str));

console.log("\nChecking invalid strings (should all be false):");
invalid.forEach(str => console.log(rgx.test(str), str));

Upvotes: 1

Nick
Nick

Reputation: 147146

The other answers don't allow for the case of .0x, which I presume is valid? I think you need to test for xxx[.xx] and .xx separately i.e.

^(\d{1,13}(\.\d{1,2})?|\.(0[1-9]|[1-9]\d?))$

Upvotes: 1

Oliver Too Eh
Oliver Too Eh

Reputation: 171

I believe the following regex should meet all of your criteria:

^(\d{1,13}($|\.\d?\d$)|\.[1-9]\d?$)

first case: 1-13 digits followed either by nothing or by a "." followed by one or two digits

second case: a "." followed by a non zero digit and at most one other digit

const valid = [
  "0",
  "0.5",
  "1.55",
  ".5",
  "1234567890123",
  "1234567890123.5",
  "1234567890123.00",
];

const invalid = [
  ".",
  ".0",
  "1.234",
  "5.",
  "12345678901234",
  "12345678901234.56",
];

const rgx = /^(\d{1,13}($|\.\d?\d$)|\.[1-9]\d?$)/

console.log("Checking valid strings (should all be true):");
valid.forEach(str => console.log(rgx.test(str), str));

console.log("\nChecking invalid strings (should all be false):");
invalid.forEach(str => console.log(rgx.test(str), str));

Upvotes: 4

Abslen Char
Abslen Char

Reputation: 3135

i think this should do most of your requirment but not all of them, limit to 9 decimal places

( /^(\d+\.?\d{0,9}|\.\d{1,9})$/ )

and this one with no decimal limit

( /^(\d+\.?\d*|\.\d+)$/ )

Upvotes: 1

Related Questions