Regex for matching certain numbers of digits - regex

The following regex will match the range 9-11 digits: /\d{9,11}/
What is the best way to write a regex matching exactly 9 or 11 digits (excluding 10)?
Using the pattern attribute of an input element, thus the regex should match the entire value of the input field. I want to accept any number containing 9 or 11 digits.

Well, you could try something like:
^\d{9}(\d{2})?$
This matches exactly nine digits followed by an optional extra-two-digits (i.e., 9 or 11 digits).
Alternatively,
^(\d{9}|\d{11})$
may work as well.
But remember that not everything necessarily has to be done with regular expressions. It may be just as easy to check the string matches ^\d*$ and that the string length itself is either 9 or 11 (using something like strlen, for example).

This regex would do
^(\d{9}|\d{11})$
or if you dont want to match it exactly
\D(\d{9}|\d{11})\D

/[^\d](\d{9}|\d{11})[^\d]/
Depending on which tool you are using, you may need to escape the (, | and ) characters.
Note that in order to not match 8, or any other number other than 9 or 11, the regex must be bounded with something to indicate that the match is surrounded by non-digit characters. Ideally, it would be some kind of word-boundary character, but the syntax for that would vary depending on the tool.
/\b(\d{9}|\d{11})\b/
works with some tools. What are you working with?

Related

Why is my regular Expression that ignore the order of the characters does not work?

I want to make a string pattern that is:
at least 7 characters long
have at least 1 digits, max 5
have at least 3 capital alphabetic characters , max 5
have at least 1 lower alphabetic characters , max 5
have at least 1 special characters , max 5
How to express this in a regular expression?
I can do something like
^((?=.*[A-Z]{3,5})(?=.*[a-z]{1,5})(?=.*[0-9]{1,5})(?=.*[.~!##$%^_&-]{1,5}))(?=.{7,20}).*$
I don't want to require this kind of order. In fact, any mixed order should be accepted, only require the number of characters.
This Match:
PASSW120P45ccb^&#%#
But this one does not
PA12S1SW2045ccb^&#%#
How can i fix this?
P&#Ass120W45ccb^%#
P&#Ass20W45cb^%#
Please have a look at https://regex101.com/r/vF2yO7/51
You need to operate with the contrary character classes, put these into non-capturing groups and repeat these:
^
(?=(?:\D*\d){1,5})
(?=(?:[^A-Z]*[A-Z]){3,5})
(?=(?:[^a-z]*[a-z]){1,5})
(?=(?:[^.\~!##$%^_&-]*[.\~!##$%^_&-]){1,5})
.{7,20}
$
See a demo on regex101.com.
The structure here is always the same, e.g. with the numbers: require anything not a number zero or more times, followed by a number and repeat the whole pattern 1-5 times. In general:
(?=(?:not_what_you_want*what_you_want){min_times, max_times})
In the expression above, all pos. lookaheads follow this scheme, [^...] negates the characters to be matched in the class and \D* is essentially the same as [^\d]*.

Regular Expression for 8 numbers followed by hyphen followed by 1 number

I'm looking for a Regular Expression that allows 8 numeric digits, follow by a "-", and then 1 more numeric digit.
Eg: 12345678-1
I tried this ^[\d*-\d+]$. Need a better solution
You can specify exact number of repetitions with {n}:
^\d{8}-\d$
^[0-9]{8}-[0-9]$ is one way.
\d also matches other things like Arabic numerals, so consider its use carefully.

Regex of exact length that matches specific group of numbers

I'm looking to build a regex that matches the following group of numbers:
10xxxxxxx
1116xxxxx
143xxxxxx
146xxxxxx
149xxxxxx
159xxxxxx
16xxxxxxx
(note the length is always 9)
where x is any digit. My best attempt yielded this:
/^1[01456][1369]*[6]*[0-9]$/
However, I can't get the length of the string to always be 9. Any ideas?
Edit: Maybe I wasn't clear enough, it needs to match those 7 cases, and ONLY those, inclusively and exclusively.
How about:
^1(?:[06]\d{2}|116|4[369]\d|59\d)\d{5}$
use this pattern
^1[01456](16|3\d|6\d|9\d|\d\d)\d{5}$
Is this what you want?
^(?=[0-9]{9}$)(?:10|1116|143|146|149|159|16)
Demo
This starts by looking at the beginning of the string for exactly 9 digits using a positive lookahead anchored to the end of the string. Then we look for any of your 7 specific groups of numbers that the string can start with.
You can use this regex:
/^1[01456][1369][0-9]{6}$/
Since 3 digits are already matched by first 3 patterns 1, [01456] and [1369] so last one must match exact 6 characters to enforce it a 9 digit input.

How can I recognize a valid barcode using regex?

I have a barcode of the format 123456########. That is, the first 6 digits are always the same followed by 8 digits.
How would I check that a variable matches that format?
You haven't specified a language, but regexp. syntax is relatively uniform across implementations, so something like the following should work: 123456\d{8}
\d Indicates numeric characters and is typically equivalent to the set [0-9].
{8} indicates repetition of the preceding character set precisely eight times.
Depending on how the input is coming in, you may want to anchor the regexp. thusly:
^123456\d{8}$
Where ^ matches the beginning of the line or string and $ matches the end. Alternatively, you may wish to use word boundaries, to ensure that your bar-code strings are properly separated:
\b123456\d{8}\b
Where \b matches the empty string but only at the edges of a word (normally defined as a sequence consisting exclusively of alphanumeric characters plus the underscore, but this can be locale-dependent).
123456\d{8}
123456 # Literals
\d # Match a digit
{8} # 8 times
You can change the {8} to any number of digits depending on how many are after your static ones.
Regexr will let you try out the regex.
123456\d{8}
should do it. This breaks down to:
123456 - the fixed bit, obviously substitute this for what you're fixed bit is, remember to escape and regex special characters in here, although with just numbers you should be fine
\d - a digit
{8} - the number of times the previous element must be repeated, 8 in this case.
the {8} can take 2 digits if you have a minimum or maximum number in the range so you could do {6,8} if the previous element had to be repeated between 6 and 8 times.
The way you describe it, it's just
^123456[0-9]{8}$
...where you'd replace 123456 with your 6 known digits. I'm using [0-9] instead of \d because I don't know what flavor of regex you're using, and \d allows non-Arabic numerals in some flavors (if that concerns you).

Limit number of alpha characters in regular expression

I've been struggling to figure out how to best do this regular expression.
Here are my requirements:
Up to 8 characters
Can only be alphanumeric
Can only contain up to three alpha characters [a-z] (zero alpha characters are valid to)
Any ideas would be appreciated.
This is what I've got so far, but it only looks for contiguous letter characters:
^(\d|([A-Za-z])(?!([A-Za-z]{3,}))){0,8}$
I'd write it like this:
^(?=[a-z0-9]{0,8}$)(?:\d*[a-z]){0,3}\d*$
It has two parts:
(?=[a-z0-9]{0,8}$)
Looksahead and matches up to 8 alphanumeric to the end of the string
(?:\d*[a-z]){0,3}\d*$
Essentially allowing injection of up to 3 [a-z] among \d*
Rubular
On rubular.com
12345678 // matches
123456789
#(#*#$
12345 // matches
abc12345
abcd1234
12a34b5c // matches
12ab34cd
123a456 // matches
Alternatives
I do think regex is the best solution for this, but since the string is short, it would be a lot more readable to do this in two steps as follows:
It must match [a-z0-9]{0,8}
Then, delete all \d
The length must now be <= 3
Do you have to do this in exactly one regular expression? It is possible to do that with standard regular expressions, but the regular expression will be rather long and complicated. You can do better with some of the Perl extensions, but depending on what language you're using, they may or may not be supported. The cleanest solution is probably to check whether the string matches:
^[A-Za-z0-9]{0,8}$
but doesn't match:
([A-Za-z].*){4}
i.e. it's an alpha string of up to 8 characters (first regular expression), but doesn't contain 4 or more alpha characters (possibly separated by other characters (second regular expression).
/^(?!(?:\d*[a-z]){4})[a-z0-9]{0,8}$/i
Explanation:
[a-z0-9]{0,8} matches up to 8 alphanumerics.
Lookahead should be placed before the matching happens.
The (?:\d*[a-z]) matches 1 alphabetic anywhere. The {4} make the count to 4. So this disables the regex from matching when 4 alphabetics can be found (i.e. limit the count to ≤3).
It's better not to exploit regex like this. Suppose you use this solution, are you sure you will know what the code is doing when you revisit it 1 year later? A clearer way is just check rule-by-rule, e.g.
if len(theText) <= 8 and theText.isalnum():
if sum(1 for c in theText if c.isalpha()) <= 3:
# valid
The easiest way to do this would be in multiple steps:
Test the string against /^[a-z0-9]{0,8}$/i -- the string is up to 8 characters and only alphanumeric
Make a copy of the string, delete all non-alphabetic characters
See if the resulting string has a length of 3 or less.
If you want to do it in one regular expression, you can use something like:
/^(?=\d*(?:[a-z]?\d*){0,3}$)[a-z0-9]{0,8}$/i
Which looks for a alphanumeric string between length 0 and 8 (^[a-z0-9]{0,8}$), but first uses a lookahead ((?=\d*(?:[a-z]?\d*){0,3}$)) to make sure that the string
has at most 3 alphabetic characters.