Regex for currency number, How can I write it shorter? - regex

^((?=.*[1-9]|0)(?:\d{1,3}))((?=.*\d)(?:\.\d{3})?)*((?=.*\d)(?:\,\d\d){1}?){0,1}$
I actually think this regular expression is very long, and mayby could be shorter. The problem is i'm not very good with regular expressions and therefore I ask you for help.
Online regex tester http://regexr.com/3a3mk
My rules:
Starting with 1, 2 or 3 positive numbers [1-9] or 0.
Adding as many . (followed by 3 numbers [0-9]) as you want.
Possibility to add a comma with 2 numbers (as decimals)
Positive results
0
0,55
1
1,60
10
10,70
100
100,80
1,10
1.000
1.000,20
10.000
10.000,03
100.000
100.000,08
1.000.000.000
1.000.000.000,10
Negative results
0,0
1,1
1,000
1000.000
0.000
0.000,10
1.000,1
1.000,100
1.0,00
1.00,00
1.000,0
01
012,10
012.123,10
a
a0
0,a
0,aa
1.a00.00
1.000.a1
[EDIT] Added more negative results

The following should suit your needs:
^(?:0|[1-9]\d{0,2})(?:\.\d{3})*(?:,\d{2})?$
Visualization by Debuggex
Demo on regex101

Edited:
^(0|[1-9][0-9]{0,2}(\.[0-9]{3})*)(,[0-9]{2})?$
matches:
^ beginning of line
[1-9] just one non-zero digit
[0-9]{0,2} between 0 and 2 digits
(\.[0-9]{3})* zero or more lots of a period and 3 digits
(0 | [1-9][0-9]{0,2}(\.[0-9]{3})*) either (i) a zero or (ii) up to three digits (the first not a zero) followed by blocks of zero or more lots of a period followed by three digits
(,[0-9]{2})? zero or one lots of a comma and 2 digits
$ end of line

You'Re right, that your expression is a bit to long. A shorter version that works with the example numbers and specifications you gave would be this:
^(0|\d{1,3})(\.\d{3})*(,\d{2})?$
Explanation:
(0|\d{1,3}) checks for a 0 or 1 to 3 digits
(\.\d{3})*checks for a dot and 3 numbers, but because of *there can also be none of them
(,\d{2})? ckecks for a comma and two digits, but again it can appear once or not at all.
Hope it helps you!

Related

Qt: Regex max. 9 digits (Int and Float)

I want to have a regex for:
- integer
- float
- max. 9 Digits
It is for Qt5
^[\d*[.,]?\d+]{0,4}$
without the {0,4} the regex works fine.
This Version works perfect, but i want to have max 9 digits
\d*[.,]?\d+
You may use
^(?!(?:\D*\d){10})\d*[.,]?\d+$
See the regex demo and the regex graph:
Details
^ - string start
(?!(?:\D*\d){10}) - fail the match if 10 or more digits is found
\d* - 0+ digits
[.,]? - an optional . or ,
\d+ - 1+ digits
$ - end of string.
This is a bit complicated. I'm also not so sure about the expression we would be wishing to design here, I'm guessing, we might want integers or floats with four digits, then we would be starting with a simple expression such as:
^\d{1,5}\.\d{1,4}$|^\d{1,9}$
The problem here would be this expression would also fail 111111.1, which is just one thing that would create sophistication. Another thing is that if we wish to also include commas.
Demo
RegEx Circuit
jex.im visualizes regular expressions:
Like Emma said, its complicated.
My suggestions is
(^\d{1}[,.]\d{1,8}$)|(^\d{2}[,.]\d{1,7}$)|(^\d{3}[,.]\d{1,6}$)|(^\d{4}[,.]\d{1,5}$)|(^\d{5}[,.]\d{1,4}$)|(^\d{6}[,.]\d{1,3}$)|(^\d{7}[,.]\d{1,2}$)|(^\d{8}[,.]\d{1,1}$)|(^\d{1,9}$)
First group checks all floats with one digit before the decimal point and 1 to 8 decimal places
Second group checks all floats with two digits before the decimal point and 1 to 7 decimal places
Third group checks all flaots with three digits before the decimal point and 1 to 6 decimal places
And so on...
The last group checks all integers with 1 to 9 digits
W/o ^ and $ in each group, it found the last 9 numbers in a 9+ digits number when using the multi line flag
jex.im

How do I limit a character appearance in a regex?

I am stuck with a problem that challenges me to create the regular expression for binary numbers (containing 0s and 1s). But the string should only match if the binary number only contains a maximum of five 1s. How do I limit a character appearance in a regex?
Examples:
01101101 is correct
01111100 is correct
10110011 is correct
01111110 is wrong
11111110 is wrong
^0*(?:10*){,5}$
Essentially this matches any combination of '1's and '0's but only allows a substring containing a single '1' character to occur five times at most.
Try it out here:
https://regex101.com/r/JKV1Uk/2
Explanation:
^ matches the beginning of the string
0* matches zero or more '0's
(?:10*){,5} matches up to 5 '1's followed by any number of zeros
$ matches the end of the string
If you engine supports lookaheads, and there can not be more than 8 times a 1 or 0 and the 1 should not occur more than 5 times, you might use:
^(?=[01]{8}$)(?!(?:0*1){6,})[01]+$
Explanation
^ Begin of the string
(?= Positive lookahead that asserts that what is on the right side
[01]{8}$ Match 8 times a 0 or 1 until the end of the string
) Close lookahead
(?! Negative lookahead that asserts that what is on the right side
(?:0*1){6,} The pattern zero or more times a 0 followed by a 1 0*1 is not repeated 6 or more times (so 0 till 5 times is valid)
) Close negative lookahead
[01]+$ Match 0 or 1 one or more times
$ The end of the string

Regex, numbers below 20k

I'm looking for a regex to validate if numbers are below 20 000.
I can't find the right solution, I have so far this:
(^([1-9]([0-9]{0,3})|20000)$)
Which works quite ok but as soon as it gets to 10 000 it gives no matches. So I have a gap from 9 999 - 20 000.
What am I doing wrong? I don't use regex for these situations, but the 3th party program required regex for such..
Thanks!
Your regex - ^([1-9]([0-9]{0,3})|20000)$ - matches numbers from 1 till 9999 and 20000.
You may use
^([1-9]\d{0,3}|1\d{4}|20000)$
See demo
Breakdown:
^ - match start of string
([1-9]\d{0,3}|1\d{4}|20000) - match one of the alternatives:
[1-9]\d{0,3} - 1 to 9 followed with 0 to 3 any digits (from 1 till 9999)
1\d{4} - 1 followed with any 4 digits (to match 10000 - 19999)
20000 - literally 20000
$ - match the end of string
I've got this:
^([01]?\d{0,4}|20000)$
Which match any number from 0 to 20 000 and allow the user to use number with leading 0 Live Demo
The ([1-9]([0-9]{0,3}) part is designed to match all numbers strictly below 2000 but you define it as: "A digit one to nine followed by zero to three digits". Now 10 000 is a one followed by four zeros: you can rewrite the part as:
[1-9][0-9]{3}|1[0-9]{4}
The full regex is now:
^[1-9][0-9]{3}|1[0-9]{4}|20000$

Regular Expression for 3 digit without 000

I want to write a regular expression on Google Form
First Character between 1 to 9
Second and Third any alphabets (Upper Case)
and next 3 characters should be number like 541 or 001 but not 000
This expression is also taking 000
[1-9][A-Z]{2}[0-9]{3}
Use alternations:
[1-9][A-Z]{2}([1-9][0-9][0-9]|[0-9][1-9][0-9]|[0-9][0-9][1-9])
See regex demo
Here,
[1-9] - matches 1 digit from 1 to 9
[A-Z]{2} - two uppercase ASCII letters
([1-9][0-9][0-9]|[0-9][1-9][0-9]|[0-9][0-9][1-9]) - 3 alternatives:
[1-9][0-9][0-9] - 3-digit numbers starting with 1
[0-9][1-9][0-9] - 3-digit numbers having 1 in the middle
[0-9][0-9][1-9] - 3-digit numbers ending with 1
Also, see this regex demo.
Use a negative look-ahead to avoid the triple zero at the end:
[1-9][A-Z]{2}(?!000)[0-9]{3}
Using the alternation operator
[1-9][1-9][1-9]|0[1-9][1-9]|00[1-9]|0[1-9]0

Can a Regex be written to find numbers in a string greater than x?

Can a Regex be written to find numbers in a string that are greater than x?
Say for example x = 1800
Can we find for that a number > 1800 which is in the strings: "3,000.00/month" | "$2800" | "150,000.00a month" | "only $1900" etc? The regex would find 3,000.00, 2800, 150,000.00 and 1900 because they are all greater than 1899.
What is this pattern that elludes me..
You can find any well-formatted number greater than a number with a regular expression, but it does get more complicated as the numbers get bigger.
Let's start with a simple example where x = 11, and you wanted to find any number in a string greater than 11. The regex you'd write would follow a pattern similar to the solution below:
(\d{3,}|[2-9]\d|1[2-9])(\.\d+)?|11\.\d*[1-9]\d*
REY
What is the purpose of first three inner alternations? The first captures any three or more digit number, the second any two digit number where the digit in the 10's place is 2-9, and the last any two digit number where the digit in the 10's place is 1 and the digit in the 1's place is 2-9. Then it optionally captures any decimal decimal digits.
The second outer alternation actually matches x in the integer part, but then checks the decimal part to ensure it is somehow greater. If you had a decimal part of 12 for x then you'd just do 120*\d*|1[3-9]\d*|2\d*.
There are two situations that will make the above pattern not work:
When a number contains commas
When a number starts with zeroes.
The example below deals with those cases as well and solves for x = 1800.
#FIND any number > 1800
(?=[1-9]) # ensure number doesn't begin with a zero
(
(\d{1,3},(?=\d{3}))*\d{2,3},\d{3}| # any number that has >= 5 digits with commas
\d{5,}| # any number that has >= 5 digits without commas
[2-9],?\d{3,}| # any 4 digit number that starts with 2-9
1,?9\d{2}| # any 4 digit number that starts with 1 then 2-9
1,?8[1-9]\d| # any 4 digit number that starts with 18 then 1-9
1,?80[1-9] # any 4 digit number that starts with 180 then 1-9
)
(\.\d+)? # any decimal digits
|1,?800\.\d*[1-9]\d* # any number whoses integer = 1800,
# ... then has a decimal with a non-zero digit.
REY
At the top of the regex is uses a look ahead to ensure a number actually starts with 1-9. Without it a number like 00005 would be confused as a five digit number.
The inner group finds all integer matches greater than 1800, just like the first example tried to match numbers greater than eleven. Probably, the only non obvious alternation is the first - (\d{1,3},(?=\d{3}))*\d{2,3},\d{3}. To find a 5+ digit number it matches 1-3 digits followed by a comma, then 2-3 digits, a comma and then the last 3 digits. Without the look ahead it would incorrectly match a non-number such as 234,23,412.
If you're going to be picky about commas, like I am being, then you're not going to be able to integrate comma and non-comma cases such as with 1,?9\d{2} => 1914 & 1,914. Having multiple ,? would lead to incorrect matches such as 1000,050, when trying to find a number greater than a million.
You could solve it in two steps: first find a number and then apply a regex to it that checks if it is greater than you number x.
As an example:
here is a regex that matches numbers from 31 to 99999, which you can adjust to your needs:
^(?:[3][1-9]|[4-9][0-9]|(^[1-9][0-9]{2,4}$))$
where
[3][1-9] - matches numbers from 31 to 39
[4-9][0-9] - matches numbers from 40 to 99
^[1-9][0-9]{2,4} - matches numbers from 100 to 9999
The last bit ^[1-9][0-9]{2,4} can be changed to ^[1-9][0-9]{2,} to match any number greater than 100