Regex pattern to find all strings which contain at most 3 alphanumeric characters

Viewed 540

I am new to regular expressions and the re module in python. I wanted to form a regex pattern which helps in identifying all strings which contain at most three alphanumeric characters. Some example patterns which I want to find are :

gut
ok
aa
na
N/A
x
c
Nil
wu
No.
E
A
I
k k
H
o
K
N
Y
Top
OK了
m
| yes
N/A |
t | T
t | T
| idk
| wsq
t | T
b | n

I have prepared a regex pattern ^[^a-zA-Z\d]*([^\n]){0,3}[^a-zA-Z\d]*$ but it fails if we have a special character in between 2 alphanumeric characters.

Can someone please help with this?

2 Answers

You might repeat 1-3 times any char except chars a-z or a digit followed by a single char a-z 0-9.

If you don't want to cross newlines, you can add those to the negated character class.

^[^a-zA-Z\d\r\n]*(?:[a-zA-Z\d][^a-zA-Z\d\r\n]*){1,3}$
  • ^ Start of string
  • [^a-zA-Z\d\r\n]* Optionally repeat matching any char except a-z, a digit or newline
  • (?: Non capture group to repeat as a whole
    • [a-zA-Z\d] Match a single char a-z or a digit
    • [^a-zA-Z\d\r\n]* Optionally repeat matching any char except a-z, a digit or newline
  • ){1,3} Close the group and repeat 1-3 times
  • $ End of string

Regex demo

Or a bit shorter using an inline modifier for case insensitive matching:

(?i)^[^a-z\d\r\n]*(?:[a-z\d][^a-z\d\r\n]*){1,3}$

I assumed that next to 3 alpha-chars at most, you'd want at least one. In that case you may want to try:

(?i)^(?!(?:.*[a-z]){4})(?:.*[a-z].*){1,3}$

See an online demo

  • (?i) - Inline modifier to match remainder case-insensitive.
  • ^ - Start line anchor.
  • (?!(?:.*[a-z]){4}) - Negative lookahead with (4x) nested non-capture group matching any char other than newline 0+ times and an alpha char.
  • (?:.*[a-z].*){1,3} - Non-capture group (1-3x) to match 0+ chars other than newline, an alpha char, and again 0+ chars other than newline.
  • $ - End line anchor.

If you are up for some alternative way you could also use re.findall() and count the matches found:

import re
s = 'N/A'
cnt = len(re.findall(r'[A-Za-z]', s))
if cnt > 0 and cnt < 4:
    print('Valid')
else:
    print('Invalid')
Related