5

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

  • 0
  • 0.5
  • 1.55
  • .5
  • 1234567890123(13 numbers before decimal)
  • 1234567890123.5
  • 1234567890123.00

Example - invalid inputs

  • .(dot),
  • .0
  • 1.234
  • 5.
  • 12345678901234(14 numbers before decimal)
  • 12345678901234.56

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));

2
  • Remove [0-9] from ~ \d[0-9]{0,13} ~ in your regex, then it will allow .5 or .6 or .1 etc Commented Mar 24, 2018 at 1:07
  • Your question is actually too broad since many other edge cases are missing. Commented Mar 24, 2018 at 1:42

4 Answers 4

4

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));

Sign up to request clarification or add additional context in comments.

Comments

1

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+)$/ )

4 Comments

yes, I can't think of a better solution than handling the xxx.xx case and .xx case separately
yes me too , i hope my input will help you slove the issue
I found out this case doesn't correctly match 5. input
I think it should be /^(\d+\.?\d{1,9}|\.\d{1,9})$/
1

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?))$

Comments

1

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));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.