I would like to check if a phone number contains exactly 3 digits - dot - 3 digits - dot - 3 digits. (e.g. 123.456.789)
So far I have this, but it doesn't work:
^(\d{3}\){2}\d{4}$
Note that an escaped bracket \) loses its special meaning in regex and the pattern becomes invalid since the capturing group is not closed.
If you want to match a dot with a regex, you need to include it to your pattern, and if you say 3 digits must be at the end there is no point in declaring 4 digits with \d{4}.
^(\d{3}\.){2}\d{3}$
^ ^
or if we expand the first group:
^\d{3}\.\d{3}\.\d{3}$
So all the fix consists in adding a dot after the second backslash and adjusting the final limiting quantifier.
Note that for mostly "stylistics" concerns (since efficiency gain is insignificant) I'd use a non-capturing group with the first regex variant:
^(?:\d{3}\.){2}\d{3}$
Related
I need regular expression for numbers that can be negative, with commas or decimal.
For examples: 12 +12 -12.0 -12,345.5466 +12,345,678,678 0.154
But not pass: "500." or "500,".
I want that 500 will return as a number without the point or the comma that connect to the number.
The regular expression that I wrote is:
[-+]?((0|([1-9](\d*|\d{0,2}(,\d{3})*)))(\.\d*[0-9])?)(?!\S)
It is work at the correct numbers (like the examples), but It don't work for the '500,' or '500.'
Assuming you want to match 500 in 500. and 500,, you should bear in mind that (?!\S) requires a whitespace or end of string immediately to the right.
You may fix the problem with
[-+]?(?:0|[1-9](?:\d{0,2}(?:,\d{3})*|\d*))(?:\.\d+)?(?!\d)
See this regex demo, and note that this can be further enhanced depending on what contexts you need to exclude.
I replaced (?!\S) with (?!\d) at the end to fail the match if there is a digit, not any non-whitespace char, immediately on the right.
Note also that I removed unnecessary groups and converted all capturing groups to non-capturing.
Also, pay attention to the (?:,\d{3})*|\d*) group, where I swapped the alternatives since the first one is more specific and should go first.
Details
[-+]? - an optional - or +
(?:0|[1-9](?:\d{0,2}(?:,\d{3})*|\d*)) - 0 or
[1-9] - a non-zero digit
(?:\d{0,2}(?:,\d{3})*|\d*) - either
\d{0,2}(?:,\d{3})* - zero, one or two digits, and then zero or more occurrences of a comma and three digits
| - or
\d* - zero or more digits
(?:\.\d+)? - an optional sequence of . and one or more digits
(?!\d) - a negative lookahead that fails the match if there is a digit immediately to the right of the current location.
Regex is great, but I can't for the life of me figure out how I'd express the following constraint, without spelling out the whole permutation:
2 of any digit [0-9]
3 of any other digit [0-9] excluding the above
4 of any third digit [0-9] excluding the above
I've got this monster, which is clearly not a good way of doing this, as it grows exponentially with each additional set of digits:
^(001112222|001113333|001114444|001115555|001116666|0001117777|0001118888|0001119999|0002220000|...)$
OR
^(0{2}1{3}2{4}|0{2}1{3}3{4}|0{2}1{3}4{4}|0{2}1{3}5{4}|0{2}1{3}6{4}|0{2}1{3}7{4}|0{2}1{3}8{4}|...)$
Looks like the following will work:
^((\d)\2(?!.+\2)){2}\2(\d)\3{3}$
It may look a bit tricky, using recursive patterns, but it may look more intimidating then it really is. See the online demo.
^ - Start string anchor.
( - Open 1st capture group:
(\d) - A 2nd capture group that does capture a single digit ranging from 0-9.
\2 - A backreference to what is captured in this 2nd group.
(?!.+\2) - Negative lookahead to prevent 1+ characters followed by a backreference to the 2nd group's match.
){2} - Close the 1st capture group and match this two times.
\2 - A backreference to what is most recently captured in the 2nd capture group.
(\d) - A 3rd capture group holding a single digit.
\3{3} - Exactly three backreferences to the 3rd capture group's match.
$ - End string anchor.
EDIT:
Looking at your alternations it looks like you are also allowing numbers like "002220000" as long as the digits in each sequence are different to the previous sequence of digits. If that is the case you can simplify the above to:
^((\d)\2(?!.\2)){2}\2(\d)\3{3}$
With the main difference is the "+" modifier been taken out of the pattern to allow the use of the same number further on.
See the demo
Depending on whether your target environment/framework/language supports lookaheads, you could do something like:
^(\d)\1(?!\1)(\d)\2\2(?!\1|\2)(\d)\3\3\3$
First capture group ((\d)) allows us to enforce the "two identical consecutive digits" by referencing the capture value (\1) as the next match, after which the negative lookahead ensures the next sequence doesn't start with the previous digit - then we just repeat this pattern twice
Note: If you want to exclude only the digit used in the immediately preceding sequence, change (?!\1|\2) to just (?!\2)
i try to write regex for get only amount, from string, i do this, it's work but i want to optimise my expression, for exemple i have
125.250.230,55
this is my regew :
\d{1,3}[\,\.]{1}\d{1,3}[\,\.]{1}\d{1,3}[\,\.]{1}\d{1,3}
i want to write it with another form with a repeat group like, but it doesn't work for me
(\d{1,3}[\,\.]{1}){6}\d{1,3}
It's unclear from your example if you want to match always 4 sets of digits separated by a comma or dot, or a variable sets of digits.
If exactly 4 sets of digits use this:
(?:\d{1,3}[.,]){3}\d{1,3}
If a variable sets of digits use this:
(?:\d{1,3}[.,])+\d{1,3}
If you want to properly match sets of 3 digits, with variable number of digits at the beginning and end, such as:
1,123,123.1
12,123,123.12
123,123,123.123
1,123,123,123,123.1
Then use this:
\d{1,3}[.,](?:\d{3}[.,])*\d{1,3}
Explanation of regex:
\d{1,3} - one to three digits (0...9)
[.,] - followed by a dot or a comma
(?: ... )* - followed by a non-capturing group; the * means zero to multiple repeats
d{3}[.,] - inside non-capturing group, expect three digits, followed by a dot or comma
\d{1,3} - followed by one to three digits
You need to make the group in your exemple non capturing. See https://www.regular-expressions.info/captureall.html
Here is your regew:
(?:\d{1,3}[\,\.]){3}\d{1,3}
I have developed the following regexp to capture float numbers.
([+-]?[0-9]+\.?[0-9]+([eE][-+]?[0-9]+)?)
It works fine for such things as 4.08955e-11 or 3.57. Now by stupid chance my parser came across 0 and failed. I guess I need to make all following the decimal point optional. But how do I do that?
Contrary to what one might think, matching every possible form of floating point number (including NaN etc) with a manageable regular expression that still discards e.g. impossibly large numbers or pseudo-octals is non-trivial.
There are some ideas about reducing the risk of false positives by using word boundaries, but note that those match boundaries between word characters (usually alphanumerics and underscore).
The scan command allows simple and reliable validation and extraction of floating point numbers:
scan $number %f
If you make all following the decimal point optional (which itself is optional) you could match values like 2.
Note that your regex does not match a single digit because you match 2 times one or more digits [0-9]+
If you only want to match float numbers or zero you could use an alternation and for example use word boundaries \b:
\b[-+]?(?:[0-9]+\.[0-9]+(?:[eE][-+]?[0-9]+)?|0)\b
Explanation
[-+]? Match optional + or -
\b Word boundary
(?: Non capturing group
[0-9]+\.[0-9]+ match one or more digits dot and one or more digits
(?:[eE][-+]?[0-9]+)? Optional exponent part
| Or
0 Match literally
) Close non capturing group
\b Word boundary
To match a float value that does not start with a dot and could be one or more digits without a dot you cold use use:
^[-+]?[0-9]+(?:\.[0-9]+)?(?:[eE][-+]?[0-9]+)?$
Perhaps using alternatives:
{[-+]?(?:\y[0-9]+(?:\.[0-9]*)?|\.[0-9]+\y)(?:[eE][-+]?[0-9]+\y)?}
as I go through the regex101 quiz/lessons, I am supposed to match an IP address (without leading zeros).
Now the following
^[^0]+[0-9]+\\.[^0]+[0-9]+\\.[^0]+[0-9]+\\.[^0]+[0-9]+$
matches 23.34.7433.33
but fails to match single digit numbers like 1.2.3.4
Why is this so, when my + is supposed to match "1 to infinite" times...?
You are in fact matching more than 2 digits for each number in the IP address because you have:
[^0]+[0-9]+
[^0]+ matches at least one character, and [0-9]+ matches at least 1 character. Both will match 'at least 2 characters' (characters being in scope of the character classes).
Also 23.34.7433.3 doesn't match your regex for the reason I stated above.
And you might try this regex for the purpose you stated:
^(?:[1-9][0-9]{0,2}\.){3}[1-9][0-9]{0,2}$
[1-9][0-9]{0,2} will match up to 3 digits, with a non leading 0.
EDIT: You mentioned in a comment that 0.0.0.0 (single digit zeroes) are to be accepted as well. The modified regex from above would be:
^(?:(?:[1-9][0-9]{0,2}|0)\.){3}(?:[1-9][0-9]{0,2}|0)$
Assuming you want to check an IPv4, I suggest you this pattern:
^(?<nb>2(?>[0-4][0-9]|5[0-5])|1[0-9]{2}|[1-9]?[0-9])(?>\.\g<nb>){3}$
I have defined a named subpattern nb to make the pattern shorter, but if you prefer, you can rewrite all and replace \g<nb>:
^(?>2(?>[0-4][0-9]|5[0-5])|1[0-9]{2}|[1-9]?[0-9])(?>\.(?>2(?>[0-4][0-9]|5[0-5])|1[0-9]{2}|[1-9]?[0-9])){3}$
Numbers greater than 255 are not allowed.
pattern details:
The goal is to describe what is allowed:
numbers with 3 digits that begins with "2" can be followed by a digit in [0-4] and a digit in [0-9] OR by 5 and a digit in [0-5] because it can exceed 255.
numbers with 3 digits that begins with "1" can be followed by any two digits.
any number with 2 digits that doesn't begin with "0"
any number with 1 digit (zero included)
If I add one by one these rules, I obtain
2(?>[0-4][0-9]|5[0-5])
2(?>[0-4][0-9]|5[0-5]) | 1[0-9]{2}
2(?>[0-4][0-9]|5[0-5]) | 1[0-9]{2} | [1-9][0-9]
2(?>[0-4][0-9]|5[0-5]) | 1[0-9]{2} | [1-9][0-9] | [0-9]
Now I have a definition for allowed numbers. I can reduce a little the size of the pattern replacing [1-9][0-9] | [0-9] by [1-9]?[0-9]
Then you only have to add the dot repeat the subpattern four times: x.x.x.x
But since there is only three dots, I write the first number and I repeat 3 times a group that contains a dot and a number:
2(?>[0-4][0-9]|5[0-5])|1[0-9]{2}|[1-9]?[0-9] # the first number
(?>\.2(?>[0-4][0-9]|5[0-5])|1[0-9]{2}|[1-9]?[0-9]){3} # the group repeated 3 times
To be sure that the string doesn't contain anything else that the IP I described, I add anchors for the start of string ^ and for the end of string $, then the string begins and ends with the IP.
To reduce the size of a pattern you can define a named group which allows to reuse the subpattern it contains,
Then you can rewrite the pattern like this:
^
(?<nb> 2(?>[0-4][0-9]|5[0-5])|1[0-9]{2}|[1-9]?[0-9] ) # named group definition
(?> \. \g<nb> ){3} # \g<nb> is the reference to the subpattern named nb
$
[0-9]+ should be [0-9]*
* matches 0 or more.
+ matches 1 or more.
You already have the case [^0] <--- this actually wrong because it will match letters also.
besides that it will match the first character that's NOT zero then at least one number after that.
It should be written as
[1-9][0-9]*
This essentially checks the first letter and sees if its a number that's between 1-9 then the next numbers(0 nums to infinite nums) after that is a number 0-9.
Then this will come out to.
^[1-9][0-9]*\.[1-9][0-9]*\.[1-9][0-9]*\.[1-9][0-9]*$
Edit live on Debuggex
cleaning it up.
^(?:[1-9][0-9]*\.){3}[1-9][0-9]*$
this should work...
^(?:[1-9][0-9]*\.|[0-9])(?:[1-9][0-9]*\.|[0-9])(?:[1-9][0-9]*\.|[0-9])(?:[1-9][0-9]*|[0-9])$
cleaned up.
^(?:(?:[1-9][0-9]*|0)\.){3}(?:[1-9][0-9]*|0)$
Your regex would match ABCDEFG999.FOOBSR888 etc, because [^0] is any character other than a zero, and bith character classes are required by the +.
I think you want this:
^[1-9]\d*(\\.[1-9]\d*){3}$
having replaced various verbose expressions with their equivalent, this is 4 groups of digits each starting with a non-zero.
Actually the problem is far more complicated, because your approach (once corrected) allows 999.999.999.999, which is not a valid IP.
It might be because you need at least two digits between two dots '.'
try using this pattern: ^[^0]+[0-9]*\.[^0]+[0-9]*\.[^0]+[0-9]*\.[^0]+[0-9]*$
to match ip address you should use this pattern:
\b(?:\d{1,3}.){3}\d{1,3}\b
taken from here:
http://www.regular-expressions.info/examples.html