Decimal or numeric values in regular expression validation
Asked Answered
P

13

89

I am trying to use a regular expression validation to check for only decimal values or numeric values. But user enters numeric value, it don't be first digit "0"

How do I do that?

Precocity answered 11/5, 2010 at 13:24 Comment(1)
Could you rephrase your question. Are you trying to craft a regular expression for an input to validate it is a numeric value? Decimals are numerics so you don't need to check for decimals specifically. What's the problem with the zero?Monotone
T
184

A digit in the range 1-9 followed by zero or more other digits:

^[1-9]\d*$

To allow numbers with an optional decimal point followed by digits. A digit in the range 1-9 followed by zero or more other digits then optionally followed by a decimal point followed by at least 1 digit:

^[1-9]\d*(\.\d+)?$

Notes:

  • The ^ and $ anchor to the start and end basically saying that the whole string must match the pattern

  • ()? matches 0 or 1 of the whole thing between the brackets

Update to handle commas:

In regular expressions . has a special meaning - match any single character. To match literally a . in a string you need to escape the . using \. This is the meaning of the \. in the regexp above. So if you want to use comma instead the pattern is simply:

^[1-9]\d*(,\d+)?$

Further update to handle commas and full stops

If you want to allow a . between groups of digits and a , between the integral and the fractional parts then try:

^[1-9]\d{0,2}(\.\d{3})*(,\d+)?$

i.e. this is a digit in the range 1-9 followed by up to 2 other digits then zero or more groups of a full stop followed by 3 digits then optionally your comma and digits as before.

If you want to allow a . anywhere between the digits then try:

^[1-9][\.\d]*(,\d+)?$

i.e. a digit 1-9 followed by zero or more digits or full stops optionally followed by a comma and one or more digits.

Tgroup answered 11/5, 2010 at 13:27 Comment(11)
+1 (but use "^[1-9][0-9]*$" for those older regex engines that don't support PCRE).Psychomotor
Make that ^([1-9]\d*|0)$ if zero is a valid number.Marylyn
thanks it's done. But i forgot say something. Users entered value also include "," character.. how do i do pleasePrecocity
sorry mike but not worked. I'm sorry my English skills but I'll try to explain my question. according to your validation expression user can not enter firs digit 0. okay it's done user can enter decimal number. okay it's done but user should enter 250,50 instead of 250.50 Your validation code don't allow to enter "," character.Precocity
No problem, I think the confusion was because the UK uses . to separate the the integral and the fractional parts of a decimal number and uses , to make long numbers more readable e.g. I would write a million as 1,000,000 I guess you are in a country that uses , as the decimal point. See this Wikipedia page for more details: en.wikipedia.org/wiki/Decimal_separatorTgroup
mike iam sorry man, sure your answer was done but again i forgot say something. It icludes "," and "." ^[1-9]\d*(\.\d+)?$ for "." ^[1-9]\d*(,\d+)?$ for "," i didnot integrate these. how can i do it?Precocity
Another update above. If this is still not exactly right then you will need to update the question to include some examples of numbers that are valid and numbers that are not valid to make things clearer.Tgroup
@Tgroup that a good expatiation you have mentioned, but regular expression get failed if i input a decimal like 0.5. i used '^[1-9]\d*(\.\d+)?$' expression, what i need is the decimal should be anything beside 0 or 0.0 :)Pinfeather
@Tgroup i got the result after some more random check :) regular expression should be ^[0-9]+\.[1-9]|[1-9]+(\.[0-9])?$Pinfeather
How would this regex pass something like 0.11 ?Irregularity
@ArshabhAgarwal the original question asked for it don't be first digit "0" so 0.11 wouldn't match. If you interpret that to mean no unnecessary leading zeroes, but the number can be 0 itself or 0 followed by a decimal fraction then you could add a case to handle this e.g. ^([1-9]\d*|0)(\.\d+)?$Tgroup
M
194

Actually, none of the given answers are fully cover the request.
As the OP didn't provided a specific use case or types of numbers, I will try to cover all possible cases and permutations.

Regular Numbers

Whole Positive

This number is usually called unsigned integer, but you can also call it a positive non-fractional number, include zero. This includes numbers like 0, 1 and 99999.
The Regular Expression that covers this validation is:

/^(0|[1-9]\d*)$/

Test This Regex

Whole Positive and Negative

This number is usually called signed integer, but you can also call it a non-fractional number. This includes numbers like 0, 1, 99999, -99999, -1 and -0.
The Regular Expression that covers this validation is:

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

Test This Regex

As you probably noticed, I have also included -0 as a valid number. But, some may argue with this usage, and tell that this is not a real number (you can read more about Signed Zero here). So, if you want to exclude this number from this regex, here's what you should use instead:

/^-?(0|[1-9]\d*)(?<!-0)$/

Test This Regex

All I have added is (?<!-0), which means not to include -0 before this assertion. This (?<!...) assertion called negative lookbehind, which means that any phrase replaces the ... should not appear before this assertion. Lookbehind has limitations, like the phrase cannot include quantifiers. That's why for some cases I'll be using Lookahead instead, which is the same, but in the opposite way.

Many regex flavors, including those used by Perl and Python, only allow fixed-length strings. You can use literal text, character escapes, Unicode escapes other than \X, and character classes. You cannot use quantifiers or backreferences. You can use alternation, but only if all alternatives have the same length. These flavors evaluate lookbehind by first stepping back through the subject string for as many characters as the lookbehind needs, and then attempting the regex inside the lookbehind from left to right.

You can read more bout Lookaround assertions here.

Fractional Numbers

Positive

This number is usually called unsigned float or unsigned double, but you can also call it a positive fractional number, include zero. This includes numbers like 0, 1, 0.0, 0.1, 1.0, 99999.000001, 5.10.
The Regular Expression that covers this validation is:

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

Test This Regex

Some may say, that numbers like .1, .0 and .00651 (same as 0.1, 0.0 and 0.00651 respectively) are also valid fractional numbers, and I cannot disagree with them. So here is a regex that is additionally supports this format:

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

Test This Regex

Negative and Positive

This number is usually called signed float or signed double, but you can also call it a fractional number. This includes numbers like 0, 1, 0.0, 0.1, 1.0, 99999.000001, 5.10, -0, -1, -0.0, -0.1, -99999.000001, 5.10.
The Regular Expression that covers this validation is:

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

Test This Regex

For non -0 believers:

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

Test This Regex

For those who want to support also the invisible zero representations, like .1, -.1, use the following regex:

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

Test This Regex

The combination of non -0 believers and invisible zero believers, use this regex:

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

Test This Regex

Numbers with a Scientific Notation (AKA Exponential Notation)

Some may want to support in their validations, numbers with a scientific character e, which is by the way, an absolutely valid number, it is created for shortly represent a very long numbers. You can read more about Scientific Notation here. These numbers are usually looks like 1e3 (which is 1000), 1e-3 (which is 0.001) and are fully supported by many major programming languages (e.g. JavaScript). You can test it by checking if the expression '1e3'==1000 returns true.
I will divide the support for all the above sections, including numbers with scientific notation.

Regular Numbers

Whole positive number regex validation, supports numbers like 6e4, 16e-10, 0e0 but also regular numbers like 0, 11:

/^(0|[1-9]\d*)(e-?(0|[1-9]\d*))?$/i

Test This Regex

Whole positive and negative number regex validation, supports numbers like -6e4, -16e-10, -0e0 but also regular numbers like -0, -11 and all the whole positive numbers above:

/^-?(0|[1-9]\d*)(e-?(0|[1-9]\d*))?$/i

Test This Regex

Whole positive and negative number regex validation for non -0 believers, same as the above, except now it forbids numbers like -0, -0e0, -0e5 and -0e-6:

/^(?!-0)-?(0|[1-9]\d*)(e-?(0|[1-9]\d*))?$/i

Test This Regex

Fractional Numbers

Positive number regex validation, supports also the whole numbers above, plus numbers like 0.1e3, 56.0e-3, 0.0e10 and 1.010e0:

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

Test This Regex

Positive number with invisible zero support regex validation, supports also the above positive numbers, in addition numbers like .1e3, .0e0, .0e-5 and .1e-7:

/^(0|[1-9]\d*)?(\.\d+)?(?<=\d)(e-?(0|[1-9]\d*))?$/i

Test This Regex

Negative and positive number regex validation, supports the positive numbers above, but also numbers like -0e3, -0.1e0, -56.0e-3 and -0.0e10:

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

Test This Regex

Negative and positive number regex validation fro non -0 believers, same as the above, except now it forbids numbers like -0, -0.00000, -0.0e0, -0.00000e5 and -0e-6:

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

Test This Regex

Negative and positive number with invisible zero support regex validation, supports also the above positive and negative numbers, in addition numbers like -.1e3, -.0e0, -.0e-5 and -.1e-7:

/^-?(0|[1-9]\d*)?(\.\d+)?(?<=\d)(e-?(0|[1-9]\d*))?$/i

Test This Regex

Negative and positive number with the combination of non -0 believers and invisible zero believers, same as the above, but forbids numbers like -.0e0, -.0000e15 and -.0e-19:

/^(?!-0?(\.0+)?(e|$))-?(0|[1-9]\d*)?(\.\d+)?(?<=\d)(e-?(0|[1-9]\d*))?$/i

Test This Regex

Numbers with Hexadecimal Representation

In many programming languages, string representation of hexadecimal number like 0x4F7A may be easily cast to decimal number 20346.
Thus, one may want to support it in his validation script.
The following Regular Expression supports only hexadecimal numbers representations:

/^0x[0-9a-f]+$/i

Test This Regex

All Permutations

These final Regular Expressions, support the invisible zero numbers.

Signed Zero Believers

/^(-?(0|[1-9]\d*)?(\.\d+)?(?<=\d)(e-?(0|[1-9]\d*))?|0x[0-9a-f]+)$/i

Test This Regex

Non Signed Zero Believers

/^((?!-0?(\.0+)?(e|$))-?(0|[1-9]\d*)?(\.\d+)?(?<=\d)(e-?(0|[1-9]\d*))?|0x[0-9a-f]+)$/i

Test This Regex

Hope I covered all number permutations that are supported in many programming languages.


Oh, forgot to mention, that those who want to validate numbers with thousands separators or radix character (E.g. 1,000, 1,000,000), you should clean all such characters (,, or . depends on the localization) first, as there may be many types of separators out there, it doesn't make sense to actually cover them all in a regex.
Remove them before the number validation, if possible:

//JavaScript
function clearSeparators(number)
{
    return number.replace(/,/g,'');
}

Similar post on my blog.

Machree answered 8/9, 2016 at 20:18 Comment(10)
It is a research article! Really the best answer on the theme on SO. Only, I would use ?: at start of all groups.Derryberry
@Derryberry The performance difference between a use of capturing and non-capturing (?:) groups is negligible compared to the readiness of the expressions here.Machree
@SlavikMeltser Do you think that the 'readiness' will suffer from using non-capturing groups? What do you mean by it? (Again thank you for the great answer!)Derryberry
@Derryberry Yes, it may seriously enlarge the expression and cause a confusion, especially with expression with a lot of groups. Why go there, just to save a couple of microseconds?Machree
This is one of the most overkill-complete answers I have ever seen, and that for a question of dubious quality at best. I love it! :DMusca
the guy she told you not to worry aboutEncarnalize
I have tested only one of your regex /^-?(0|[1-9]\d*)(\.\d+)?$/ from fractional positive negative . It returns true for 1.2.2. also.Gond
Sorry @The_ehT, but you are wrong. The regex /^-?(0|[1-9]\d*)(\.\d+)?$/ doesn't match the string 1.2.2. (regex101.com/r/CATnTj/2). Maybe there is something wrong with your implementation?Machree
Thank you very much for your answer. Pertaining to /^(0|[1-9]\d*)?(\.\d+)?(?<=\d)$/ (Fractional Numbers, Positive, second example), it is notable that values such as 3. and and 001 do not match in your linked example. Given these are equivelant to 3 and 1, which do match, I find it... well, "notable" :) that is all.Caponize
See here for a version of most of these that doesn't use lookarounds, in case your regex engine doesn't support them... They are written in escaped Emacs syntax, but to use them elsewhere one just has to remove all the `\`'s.Charlenecharleroi
T
184

A digit in the range 1-9 followed by zero or more other digits:

^[1-9]\d*$

To allow numbers with an optional decimal point followed by digits. A digit in the range 1-9 followed by zero or more other digits then optionally followed by a decimal point followed by at least 1 digit:

^[1-9]\d*(\.\d+)?$

Notes:

  • The ^ and $ anchor to the start and end basically saying that the whole string must match the pattern

  • ()? matches 0 or 1 of the whole thing between the brackets

Update to handle commas:

In regular expressions . has a special meaning - match any single character. To match literally a . in a string you need to escape the . using \. This is the meaning of the \. in the regexp above. So if you want to use comma instead the pattern is simply:

^[1-9]\d*(,\d+)?$

Further update to handle commas and full stops

If you want to allow a . between groups of digits and a , between the integral and the fractional parts then try:

^[1-9]\d{0,2}(\.\d{3})*(,\d+)?$

i.e. this is a digit in the range 1-9 followed by up to 2 other digits then zero or more groups of a full stop followed by 3 digits then optionally your comma and digits as before.

If you want to allow a . anywhere between the digits then try:

^[1-9][\.\d]*(,\d+)?$

i.e. a digit 1-9 followed by zero or more digits or full stops optionally followed by a comma and one or more digits.

Tgroup answered 11/5, 2010 at 13:27 Comment(11)
+1 (but use "^[1-9][0-9]*$" for those older regex engines that don't support PCRE).Psychomotor
Make that ^([1-9]\d*|0)$ if zero is a valid number.Marylyn
thanks it's done. But i forgot say something. Users entered value also include "," character.. how do i do pleasePrecocity
sorry mike but not worked. I'm sorry my English skills but I'll try to explain my question. according to your validation expression user can not enter firs digit 0. okay it's done user can enter decimal number. okay it's done but user should enter 250,50 instead of 250.50 Your validation code don't allow to enter "," character.Precocity
No problem, I think the confusion was because the UK uses . to separate the the integral and the fractional parts of a decimal number and uses , to make long numbers more readable e.g. I would write a million as 1,000,000 I guess you are in a country that uses , as the decimal point. See this Wikipedia page for more details: en.wikipedia.org/wiki/Decimal_separatorTgroup
mike iam sorry man, sure your answer was done but again i forgot say something. It icludes "," and "." ^[1-9]\d*(\.\d+)?$ for "." ^[1-9]\d*(,\d+)?$ for "," i didnot integrate these. how can i do it?Precocity
Another update above. If this is still not exactly right then you will need to update the question to include some examples of numbers that are valid and numbers that are not valid to make things clearer.Tgroup
@Tgroup that a good expatiation you have mentioned, but regular expression get failed if i input a decimal like 0.5. i used '^[1-9]\d*(\.\d+)?$' expression, what i need is the decimal should be anything beside 0 or 0.0 :)Pinfeather
@Tgroup i got the result after some more random check :) regular expression should be ^[0-9]+\.[1-9]|[1-9]+(\.[0-9])?$Pinfeather
How would this regex pass something like 0.11 ?Irregularity
@ArshabhAgarwal the original question asked for it don't be first digit "0" so 0.11 wouldn't match. If you interpret that to mean no unnecessary leading zeroes, but the number can be 0 itself or 0 followed by a decimal fraction then you could add a case to handle this e.g. ^([1-9]\d*|0)(\.\d+)?$Tgroup
S
9

I had the same problem, but I also wanted ".25" to be a valid decimal number. Here is my solution using JavaScript:

function isNumber(v) {
  // [0-9]* Zero or more digits between 0 and 9  (This allows .25 to be considered valid.)
  // ()? Matches 0 or 1 things in the parentheses.  (Allows for an optional decimal point)
  // Decimal point escaped with \.
  // If a decimal point does exist, it must be followed by 1 or more digits [0-9]
  // \d and [0-9] are equivalent 
  // ^ and $ anchor the endpoints so tthe whole string must match.
  return v.trim().length > 0 && v.trim().match(/^[0-9]*(\.[0-9]+)?$/);
}

Where my trim() method is

String.prototype.trim = function() {
  return this.replace(/(^\s*|\s*$)/g, "");
};

Matthew DesVoigne

Suprarenal answered 4/5, 2011 at 20:18 Comment(0)
Z
8

I've tested all given regexes but unfortunately none of them pass those tests:

    String []goodNums={"3","-3","0","0.0","1.0","0.1"};
    String []badNums={"001","-00.2",".3","3.","a",""," ","-"," -1","--1","-.1","-0", "2..3", "2-", "2...3", "2.4.3", "5-6-7"};

Here is the best I wrote that pass all those tests:

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

enter image description here

Zeuxis answered 1/7, 2015 at 19:14 Comment(5)
So far yours is the best, but it also fails in the following: a <- c("2..3", "2-", "2...3", "2.4.3", "5-6-7") Do you have any solution for these?Unciform
Nope, doesn't fail... I checked it just now.Zeuxis
I checked now again and it fails (at least in R environment). check this out: pastebin.com/D1MwKgR3Unciform
Thanks for pasting, it was easier to understand the problem. so to fix that or in other words to match also to Perl (as in your case) simply added start|end tokens to make engine understand that each group should act individually. It's make the regex to be 4 chars longer, but fix the problem for you also.Zeuxis
Guys... don't forget it is really simple to just add simple checks afterwards: it does not have to fit in one regex.Cryptomeria
B
4

A simple regex to match a numeric input and optional 2 digits decimal.

/^\d*(\.)?(\d{0,2})?$/

You can modify the {0,2} to match your decimal preference {min, max}


Snippet for validation:

const source = document.getElementById('source');
source.addEventListener('input', allowOnlyNumberAndDecimals);

function allowOnlyNumberAndDecimals(e) {
  let str = e.target.value
  const regExp = /^\d*(\.)?(\d{0,2})?$/

  status = regExp.test(str) ? 'valid' : 'invalid'

  console.log(status + ' : ' + source.value)
}
<input type="text" id="source" />
Breedlove answered 26/1, 2021 at 12:8 Comment(1)
thanks, this works for my case good cases = [2, 2.2, 2., 2.22]Supplant
C
2

Here is a great working regex for numbers. This accepts number with commas and decimals.

/^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/
Caulis answered 4/8, 2014 at 18:30 Comment(1)
Thanks and here is the slightly modified version which accommodates percentage as well: -?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d*)%?Cabbala
U
2

Here is my regex for validating numbers:

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

Valid numbers:

String []validNumbers={"3","-3","0","0.0","1.0","0.1","0.0001","-555","94549870965"};

Invalid numbers:

String []invalidNumbers={"a",""," ","-","001","-00.2","000.5",".3","3."," -1","--1","-.1","-0"};
Unclinch answered 5/12, 2015 at 15:33 Comment(0)
F
1

Below is the perfect one for mentioned requirement :

^[0-9]{1,3}(,[0-9]{3})*(([\\.,]{1}[0-9]*)|())$
Freehanded answered 9/7, 2015 at 12:57 Comment(1)
Shenal, yours fails with negative numbers and also with zeros at the start with yours it gave: false to "-3" and "-3.3". but gave true to "001". By the way I don't think there is such a thing as perfect in programming world. In my opinion it's always a question of compromise.Zeuxis
K
1

/([0-9]+[.,]*)+/ matches any number with or without coma or dots

it can match

         122
         122,354
         122.88
         112,262,123.7678

bug: it also matches 262.4377,3883 ( but it doesn't matter parctically)

Kana answered 9/5, 2016 at 8:49 Comment(3)
And also matches 0,,,,.,.,.,.,.,,,,.,,,,,,,,.,.,.,...........,,,,,.,.,.,.,.,.,,,,,,,,.....,,.,, ;-)Machree
That doesn't matter practicallyKana
Well, it depends on the input and what you do with it at the end. For example, if this regex is your only gate for verifying a number before you put it in the DB, you are in a big trouble, as it may break things up or worse, open a vulnerability and provide a backdoor to your system.Machree
L
1

Try this code, hope it will help you

String regex = "(\\d+)(\\.)?(\\d+)?";  for integer and decimal like 232 232.12 
Lenient answered 31/10, 2017 at 10:42 Comment(0)
T
0

if you need to validate decimal with dots, commas, positives and negatives try this:

Object testObject = "-1.5";
boolean isDecimal = Pattern.matches("^[\\+\\-]{0,1}[0-9]+[\\.\\,]{1}[0-9]+$", (CharSequence) testObject);

Good luck.

Takahashi answered 17/2, 2015 at 14:22 Comment(0)
M
0

My regex

/^((0((\.\d*[1-9]\d*)?))|((0(?=[1-9])|[1-9])\d*(\.\d*[1-9]\d*)?))$/
Mel answered 19/10, 2022 at 13:29 Comment(0)
H
-1

The regular expression ^(\d+(\.\d+)?)$ works for every number. For demonstration I embedded it into a runnable JS-fiddle:

const source = document.getElementById('source');
source.addEventListener('input', allowOnlyNumberAndDecimals);

function allowOnlyNumberAndDecimals(e) {
  let str = e.target.value
  const regExp = /^(\d+(\.\d+)?)$/

  let status = regExp.test(str) ? 'valid' : 'invalid'

  console.log(status + ' : ' + source.value)
}
body {
  height: 100vh;
  background: pink;
  color: black;
  justify-content: center;
  align-items: center;
}
<h1>VALIDATE ALL NUMBERS :)<h1>
<input type="text" id="source" />
Hypnogenesis answered 4/3, 2021 at 4:3 Comment(1)
Actually the question was only about a regular-expression. This was answered already in different forms, always by giving only the (regular-)expression. Your answer simply wraps an already answered regex into a runable JS-fiddle. The essentials of it is regExp = /^(\d+(\.\d+)?)$/. Please explain why your answer (the regex) differs from the others :-)Wetzel

© 2022 - 2024 — McMap. All rights reserved.