Validating a phone number with a custom rule possibly using nested groups - regex

I am trying to write a regex for validating phone numbers.
We have custom rules, i.e. the phone number must meet the following pattern:
+ or 00 as a prefix
One to three digits
An optional space or hyphen
Then one to n digits (n is still constrained by the rule for total character count below
The total number of characters must not exceed 28.
Here is the regex I have come up with:
/^((\+|00)(\d{1,3})[\s-]?)(\d{1,23}){1,28}$/
I am sure it can be simplified. Can someone please help?

This part of your pattern (\d{1,23}){1,28} matches 1-23 digits followed by repeating that 1-28 times and the maximum is 28×23=644 (Thank you #Toto)
You could check if the string consists of 1-28 times the listed characters using a positive lookahead (?=[+\d -]
The last part currently is \d{1,}, but you could specify a minimum length if you don't want to match +1 1
Note that \s could also possibly match a newline.
^(?=[+\d -]{1,28}$)(?:\+|00)\d{1,3}[ -]?\d{1,}$
Regex demo

Related

Using regex to match numbers which have 5 increasing consecutive digits somewhere in them

First off, this has sort of been asked before. However I haven't been able to modify this to fit my requirement.
In short: I want a regex that matches an expression if and only if it only contains digits, and there are 5 (or more) increasing consecutive digits somewhere in the expression.
I understand the logic of
^(?=\d{5}$)1*2*3*4*5*6*7*8*9*0*$
however, this limits the expression to 5 digits. I want there to be able to be digits before and after the expression. So 1111345671111 should match, while 11111 shouldn't.
I thought this might work:
^[0-9]*(?=\d{5}0*1*2*3*4*5*6*7*8*9*)[0-9]*$
which I interpret as:
^$: The entire expression must only contain what's between these 2 symbols
[0-9]*: Any digits between 0-9, 0 or more times followed by:
(?=\d{5}0*1*2*3*4*5*6*7*8*9*): A part where at least 5 increasing digits are found followed by:
[0-9]*: Any digits between 0-9, 0 or more times.
However this regex is incorrect, as for example 11111 matches. How can I solve this problem using a regex? So examples of expressions to match:
00001459000
12345
This shouldn't match:
abc12345
9871234444
While this problem can be solved using pure regular expressions (the set of strictly ascending five-digit strings is finite, so you could just enumerate all of them), it's not a good fit for regexes.
That said, here's how I'd do it if I had to:
^\d*(?=\d{5}(\d*)$)0?1?2?3?4?5?6?7?8?9?\1$
Core idea: 0?1?2?3?4?5?6?7?8?9? matches an ascending numeric substring, but it doesn't restrict its length. Every single part is optional, so it can match anything from "" (empty string) to the full "0123456789".
We can force it to match exactly 5 characters by combining a look-ahead of five digits and an arbitrary suffix (which we capture) and a backreference \1 (which must exactly the suffix matched by the look-ahead, ensuring we've now walked ahead 5 characters in the string).
Live demo: https://regex101.com/r/03rJET/3
(By the way, your explanation of (?=\d{5}0*1*2*3*4*5*6*7*8*9*) is incorrect: It looks ahead to match exactly 5 digits, followed by 0 or more occurrences of 0, followed by 0 or more occurrences of 1, etc.)
Because the starting position of the increasing digits isn't known in advance, and the consecutive increasing digits don't end at the end of the string, the linked answer's concise pattern won't work here. I don't think this is possible without being repetitive; alternate between all possibilities of increasing digits. A 0 must be followed by [1-9]. (0(?=[1-9])) A 1 must be followed by [2-9]. A 2 must be followed by [3-9], and so on. Alternate between these possibilities in a group, and repeat that group four times, and then match any digit after that (the lookahead in the last repeated digit in the previous group will ensure that this 5th digit is in sequence as well).
First lookahead for digits followed by the end of the string, then match the alternations described above, followed by one or more digits:
^(?=\d+$)\d*?(?:0(?=[1-9])|1(?=[2-9])|2(?=[3-9])|3(?=[4-9])|4(?=[5-9])|5(?=[6-9])|6(?=[7-9])|7(?=[89])|8(?=9)){4}\d+
Separated out for better readability:
^(?=\d+$)\d*?
(?:
0(?=[1-9])|
1(?=[2-9])|
2(?=[3-9])|
3(?=[4-9])|
4(?=[5-9])|
5(?=[6-9])|
6(?=[7-9])|
7(?=[89])|
8(?=9)
){4}
\d+
The lazy quantifier in the first line there \d*? isn't necessary, but it makes the pattern a bit more efficient (otherwise it initially greedily matches the whole string, requiring lots of failing alternations and backtracking until at least 5 characters before the end of the string)
https://regex101.com/r/03rJET/2
It's ugly, but it works.

Regex: How to find a phone number (or number sequence) that begins with a particular single digit (multiple numbers on the same line)

Newbie question but how can I check for instances where there are multiple numbers on the same line. For instance, the content reads for example contact 408-555-5454 or reach out to 408-555-4545. Right now the best I can do is ^4 but that's only catching multiple things if the mutliline flag is tured on. Any idea.
You could try the regex below
/4\d{2}(-| )?\d{3}(-| )?\d{4}/g
This of course assumes that you're looking for numbers that start with 4. You can have a look at the Regex Snippet here and you can experiment with trying different variations of the regex to suit your needs.
here's a key to the regex elements included:
4 = matches the literal number 4
\d{2} = matches 2 digits (0-9).
(-| )? = matches either a hyphen or single space but makes it not required. ie you can have a space or hyphen or not.
\d{3} = matches 3 digits (0-9)
Same as #3 above
\d{4} = matches 4 digits (0-9)
the g flag will ensure that you're searching through the whole text and not stopping after the first match.
If you like the answer please Accept it :)

Different regex conditions on same string

I am trying to implement a regex for phone numbers, based on our business logic.
What the customer wants is that the phone must contain between 8 and 15 characters of numbers, and also can contain any spaces and dots anywhere which doesn't add to the count of numbers. So, theoretically this should be valid:
3 .... 44444444
Because it contains 9 numbers.
I can't really go further on
~[0-9\.\ ]{8,15}$
but obviously it counts dots and spaces to the limit too.
Is it even possible to implement it via regex?
A Regex attempt:
^(?:[ .]*\d){8,15}[ .]*$
This will match 8 to 15 digits, with any number of space or dot happening anywhere in between.
The non-captured group, (?:[ .]*\d), matches any digit preceded by any number of dot or space, {8,15} ensures the range on numbers
[ .]*$ matches any number of dot or space at the end
Demo
As far as I know, regular expressions cannot validate this. However you could maybe globally remove all whitespace and dots and then try to match a regex that is ^[[:digit:]]{8,15}$

Need a Regex that contains at least one number, zero or more letters, no spaces, min/max

I need a regular expression that will match a string that contains:
at least one number
zero or more letters
no other characters such as spaces
The string must also be a minimum of 8 characters and a maximum of 13 characters.
Placement of the numbers and/or letters within the 8-13 character string does not matter. I haven't figured out how to make sure that the string contains a number, but here are some expressions that don't work because they are picking up spaces in the online tool Regexr. Take a look below:
- ([\w^/s]){8,13}
- ([a-zA-Z0-9]){8,13}
- ([a-zA-Z\d]){8,13}
I am specifically looking to exclude spaces and special characters. The linked and related questions all appear to allow for these characters. This is not for validating passwords, it is for detecting case numbers in natural language processing. This is different from "Password REGEX with min 6 chars, at least one letter and one number and may contain special characters" because I am looking for at least one number but zero or more letters. I also do not want to return strings that contain any special characters including spaces.
This is a typical password validation with your requirements.
Note that this will also match 8-13 digits as well (but it is requested).
Ten million + 1 (and counting) happy customers ..
^(?=.*\d)[a-zA-Z\d]{8,13}$
Explained
^ # Beginning of string
(?= .* \d ) # Lookahead for a digit
[a-zA-Z\d]{8,13} # Consume 8 to 13 alphanum characters
$ # End of string
I've seen the answer above (by sln) everywhere over the internet, but as far as I can tell, it is NOT ACCURATE.
If your string contains 8 to 13 characters with no numbers this expression will match it, because it uses the * quantifier on the wildcard character . in the positive lookahead.
In order to match at least 1 digit, 1 A-Z and 1 a-z in a password that's at least 8 characters long, you'll need something like this:
(?=.{1,7}\d)(?=.{1,7}[a-z])(?=.{1,7}[A-Z])[a-zA-Z\d]{8,13}
it uses 3 lookaheads:
(?=.{1,7}\d)
(?=.{1,7}[a-z])
(?=.{1,7}[A-Z])
each time, it looks for the target (eg the first digit) but allows 1 to 7 occurances of any character before it.
Then it will match 8 to 13 alphanumeric characters.
NOTE to Powershell users:
Use a search group to be able to extract a result
$password = [regex]::match($string-to-search,'(?=.{1,7}\d)(?=.{1,7}[a-z])(?=.{1,7}[A-Z])([a-zA-Z\d]{8,13})').Groups[1].Value

Regular Expressions for specific number patterns

I have an invoice in readable form. I need to extract PO number from the invoice. The PO numbers come in a particular format (26123456, 26234567). It starts with 26 and has 6 numbers following it. I am trying to extract it using regular expressions.
I have passed this as my parameters.
[26]\d{6,6} also I have tried this ^[26]\d{6,6}
However, the problems I am facing are:
If the PO number is 26454545 and before the PO number there are other numbers in the invoice such as Telephone numbers which have in them a substring with 26, its extracting that as well. For ex. 12345678987 this number is being extracted as well since there is 2 and 6 present in the substring.
Remove the character class and add word boundaries.
\b26\d{6}\b
[26] will match a single character from the given list whether it may be 2 or 6. To match a number 26, just use the number as it is.
By adding \b at the start and at the end helps to match a complete number. Since \b matches between a word character and a non-word character. You could also use assertions here like (?<!\d)26\d{6}(?!\d) .
There is another pattern that i want to extract 12300012345. after the first three numbers there are always 3 zeros followed by 5 numbers.
\b\d{3}000\d{5}\b
If you want to combine the both, then you need to use the regex alternation operator |
\b26\d{6}\b|\b\d{3}000\d{5}\b