Regex: combination of integers, decimals, ranges and fractions - javascript

I'm struggling to build a Regex which validates integers, decimals, fractions, ranges, as well as complex combinations of integers and ranges or fractions.
So far, with the help of another StackOverflow question, I've come up with this:
/^(?:(?:0|[1-9]\d*)(?:[.,]\d+)?|([1-9]\s)?([1-9]\d*[/-][1-9]\d*-?)+)$/
This validates:
Integers without leading zeros (01 is invalid)
Decimals with only one leadig zero (001,2 is invalid)
Fractions without decimals (1/2 is valid, but 1,2/2,4 isn't).
Ranges without decimals (1-2 is valid, but 1,2-2,4 isn't)
Combinations of one digit units and fractions or ranges (1 1/2). For units, the integer rules apply (no commas, etc).
Combinations of ranges and fractions (1/2-1/4 is valid, but 1/2- shouldn't be)
But I'm having trouble validating some complex combinations of integers and ranges which contain integers with fractions. For instance, this should also valid:
1-1 1/2
Using my current regex, how could I validate this part?
Thanks!

If the current pattern validates a single requirement, you can optionally repeat it preceded by a space.
^(?:(?:[1-9]\d+|[1-9]\d*[/-][1-9]\d*|(?:0|[1-9]\d*),\d+)|[1-9](?:[/-][1-9]\d*)?(?:[ -][1-9][/-][1-9]\d*)?)$
Explanation
^ Start of string
(?: Non capture group
(?: non capture group
[1-9]\d+ Match a digit 1-9 and 1+ times a digit 0-9
| Or
[1-9]\d*[/-][1-9]\d*
| or
(?:0|[1-9]\d*),\d+ Match either 0 or a digit 1-9 and optional
digits followed by , and 1+ digits
) close non capture group
| Or
[1-9] Match a single digit 1-9
(?:[/-][1-9]\d*)? Optionally match / or - and a digit 1-9 followed by optional digits
(?:[ -][1-9][/-][1-9]\d*)? Optionally match either a space or - and then a digit 1-9, either / or -, then a digit 1-9 and optional digits 0-9
) Close non capture group
$ End of string
Regex demo

Related

Why this regex fails when there is an extra zero?

I have created this regex to match dollar amounts more than $9,000.00.
\$(?=.{6,11}$)\d{1,3}(?:,\d{3})*
But it fails in cases like this,
$25,000.00. Text Goes here
$1,000,000.00
However it works in cases like this,
$25,000.0. T
$25,000.00
$999,000.00
How to fix this regex?
Some issues in your regex:
The look ahead assertion requires the that match can only start in the final 11 characters of the input string, since it has the $ anchor after at least 6 and at most 11 characters. So it is no surprise that "$25,000.00. Text Goes here" does not match. I suppose you don't want that $ anchor, and then the 11 is not useful anymore either.
The look ahead assertion requires that at least 6 characters follow after the currency symbol, however that could include non-digit characters, and so your regex will match the amount in `$300 oh" (6 characters follow after currency symbol).
There is no provision in your regex for decimals even though you say it works for examples that have decimals. But it will not include those decimals in the match. For instance, for input "$300,000.50" it will only match "$300,000" and not the 50 cents. You would need to accept an optional decimal point followed by one or two digits and then require there are no more decimal digits with a negative look-ahead.
The look-ahead assertion is not the right place to impose a maximum amount, because when you remove the $ (see first point) you must still require that there are no more digits after the 11th position. Instead, just remove the look-ahead assertion and match the patterns you want in more detail. There are just two options: either you have 2 or 3 digits followed by one digit group (for amounts between 10,000 and 999,999.99) or you have 1 to 3 digits followed by two digit groups (for amounts between 1,000,000 and 999,999,999.99). To avoid that more digits follow when no decimal part exists, use a negative look-ahead assertion: (?![,.]?\d).
All this is taken into account in this correction:
\$(?:\d{2,3}(?:,\d{3})|\d{1,3}(?:,\d{3}){2})((?![,.]?\d)|\.\d\d?(?!\d))
On regex101
To allow the same numbers without commas, add \d{5,9} as an option:
\$(?:\d{2,3}(?:,\d{3})|\d{1,3}(?:,\d{3}){2}|\d{5,9})(?:(?![,.]?\d)|\.\d\d?(?!\d))
On regex101
Totally new answer. After closer inspection I see that they have revised
the specifications on this question.
I am submitting this solution based on a $10,000.00 - $999,999,999.00 range
of unacceptable cash amounts. The comma's and decimal are optional.
There cannot be more than 3 consecutive decimal numbers after the period.
Ah, other specifications are dubious.
Note that a text representation of leading zero's is not allowed, which is a
distinction worth investigating as digits \d class is covers characters 0-9.
It is hard, if not impossible to match to infinity.
For example, the OP requested to match cash greater than $9,000 (Ah $10,000).
Regex has no representation of quantifiers representing infinity therefore
#Trincot tried to talk him into a max cash amount number to cap it.
In reality, you can only match the infinite with a negative of the finite.
So it is in the cosmos as it is in regex.
The only real way to match a number greater than another number is to
state that it is not in a finite range. In this case not in the range $0 - $9,999.
In this case they have established a range that the cash cannot be in.
That apparently is this $10,000.00 - $999,999,999.00 range, which
absolutely does not represent all values greater than $10,000.00
My original answer was to match $0 - $9,000 (original minimum) then post that regex in a negative assertion, thereby matching the infinite set of values
greater than $9,000 which was and is the only answer to matching cash values greater than
a fixed amount.
In the end, parsing values is only a preamble to getting it into a float
and there is no way to glean the final value ahead of that conversion.
Therefore, this is really an exercise in futility.
To that end :
$10,000.00 - $999,999,999.00
\$[1-9](?:\d{1,2}(?:,?\d{3}){1,2}|(?:,?\d{3}){2})(?:\.\d{0,2})?(?![,.]?\d)
https://regex101.com/r/1h4XW9/1
\$ [1-9]
(?:
\d{1,2}
(?: ,? \d{3} ){1,2}
| (?: ,? \d{3} ){2}
)
(?: \. \d{0,2} )?
(?! [,.]? \d )

Regex up to 4-digit number and/or up to 4 decimal places

I need a regex that allows UP TO 4 digit number AND/OR 4 decimal places.
ONLY allowed format examples (I'm just using only 1s to make the format looks simple, it all should be [0-9])
1
1.1
1.11
1.111
1.1111
11
11.1
11.11
11.111
11.1111
111
111.1
111.11
111.111
111.1111
1111
1111.1
1111.11
1111.111
1111.1111
So far the closest one I've gotten --
"^[0-9]{0,4}(?:.[0-9]{0,4}$)"
It works pretty good when I enter numbers + decimals.
However, if I just enter numbers without decimals, I can enter 4+ number digits, which it should not.
The ^[0-9]{0,4}(?:.[0-9]{0,4}$) only seems to be almost working for you. As . is unescaped, it matches any char including digits, and you have an impression it works.
Once you properly escape . with a literal \, it will stop "working", because this will require a dot.
You need to use
/^\d{0,4}(?:\.\d{0,4})?$/
"^[0-9]{0,4}(?:[.][0-9]{0,4})?$"
Details:
^ - start of string
[0-9]{0,4} / \d{4} - zero to four digits
(?:\.[0-9]{0,4})? - an optional occurrence of a . and then zero to four digits
$ - end of string.

Javascript regex positive less than 10000 than can be decimal

I need a regex for a number than can be decimal and less than 10000 with max 2 digits after decimal.
I tried
/^([0-9]{1,4})+(\.[0-9]{0,2})$/
but it returns true for 44555.54 for example.
In your regex you are using + which is using for one or more repetition and which leads to match any length of digit and make decimal part non-greedy(using?) to make it optional.
^[0-9]{1,4}(\.[0-9]{0,2})?$
or using \d for digit character class.
^\d{1,4}(\.\d{0,2})?$

Indian pincode validation regex - Only six digits, shouldn't start with `0`

I have tried Regex accept numeric only. First character can't be 0 and What is the regex for "Any positive integer, excluding 0" however that didn't work as per my requirements.
I want exact 6 digit numeric number but shouldn't start with 0
I've tried
^[1-9][0-9]{6}*$
^([^0][0-9]){6}$
...
Need fine tuning.
The problem with ^[1-9][0-9]{6}*$ is it is an invalid regex because of {6}* and ^([^0][0-9]){6}$ is that it is allowing any character that is not 0 followed by six digits.
Use
^[1-9][0-9]{5}$
Explanation:
^: Starts with anchor
[1-9]: Matches exactly one digit from 1 to 9
[0-9]{5}: Matches exactly five digits in the inclusive range 0-9
$: Ends with anchor
Regex101 Playground
HTML5 Demo:
input:invalid {
color: red;
}
<input type="text" pattern="[1-9][0-9]{5}" />
This regular expression covers;
PIN code doesn't start from zero
Allows 6 digits only
Allows 6 consecutive digits (e.g. 431602)
Allows 1 space after 3 digits (e.g. 431 602)
([1-9]{1}[0-9]{5}|[1-9]{1}[0-9]{3}\\s[0-9]{3})
Some websites and banks have the habit of spacing pincode after 3 digits.
To match both 515411 and 515 411 the following pattern will help.
^[1-9]{1}[0-9]{2}\s{0,1}[0-9]{3}$
^[1-9]{1} - PIN Code that starts with digits 1-9
[0-9]{2} - Next two digits may range from 0-9
\s{0,1} - Space that can occur once or never
[0-9]{3}$ - Last 3 needs to be digits ranging from 0-9

What regex for jQuery satisfies these conditions?

I have a field for which can have:
Up to potentially 2 decimals places
Up to potentially 6 non-decimal places
No more than 8 digits altogether (the max 2 decimals plus max 6 non-decimals)
Be a positive number
So correct inputs would be range from 0.01 to 999999.99, and trailing zeroes isn't an issue, so 4.00 is just as fine as 4.
Try this pattern:
^[0-9]{1,6}(?:\.[0-9]{1,2}0*)?$
If you want to allow leading and trailing whitespace, add \s* to the beginning and the end of the pattern, right after ^ and right before $.
That said, this task is something you might want to accomplish without regex. Why don't you just read the value of the input, parse it and then simply perform a numeric validation? You could even round the input to two decimal places.
You could try something like so:
Up to potentially 2 decimals places: (\.\d{1,2})? - This will match a decimal point followed by a minimum of 1, and a maximum of 2 digits. This is optional.
Up to potentially 6 non-decimal places: \d{1,6} - This will match a minimum of 1 digit and a maximum of 6 digits.
No more than 8 digits altogether (the max 2 decimals plus max 6 non-decimals): You can combing the two above to get this: \d{1,6}(\.\d{1,2})?.
Be a positive number: Change the above to this: ^\d{1,6}(\.\d{1,2})?$. This should make sure that any number you pass to it, does not start with a negative sign. The ^ and $ anchors instruct the regex engine to start matching at the beginning of the string and complete the matching at the end. This should allow you to be sure that the string you are matching is indeed a number.
That being said, you should really be doing numerical range checks using the appropriate mathematical operations which your language (in this case JavaScript) provides. A small change in the numerical range you are after will most likely bring a large change in your regular expression.
This might validate it
# /^(?=.*[1-9].*$)(?=[.]?(?:\d[.]?){1,8}$)(?=\d{0,6}(?:[.]\d{0,2})?$)/
^
(?= # must be a positive number
.* [1-9] .* $
)
(?=
[.]?
(?: # 1 to 8 digits
\d
[.]?
){1,8}
$
)
(?=
\d{0,6} # 0 to 6 non-decimal places
(?:
[.] # 0 to 2 decimal places
\d{0,2}
)?
$
)

Categories