-2

pls check the regex below

import re

passwords = ['aaa5aa', 'adsfgg', 'e42dsf425']

regex = r'\w{3}\d{1}\w{2}'

for p in passwords:
    if re.findall(regex, p):
        print(p)

I dont uderstand why this regex match both: aaa5aa and e42dsf425. I expected to see only aaa5aa as we have \d{1} in the pattern.

Thank you very much, have a nice day!

Paweł

Jan
  • 42,290
  • 8
  • 54
  • 79
  • If your goal is to test these against your exact pattern try to change `re.findall` to `re.match` to test against a boolean return on a whole match. That should also forfeit the need for anchors `^` and `$`. – JvdV May 04 '21 at 11:45

2 Answers2

2

The short-hand \w includes \d. Use a character class instead:

[a-z]{3}\d[a-z]{2}

In Python:

import re

passwords = ['aaa5aa', 'adsfgg', 'e42dsf425']

regex = r'[a-z]{3}\d[a-z]{2}'

for p in passwords:
    if re.search(regex, p):
        print(p)

See a demo on ideone.com.


\w is a short-hand for [a-zA-Z0-9_], whereas \d is [0-9].

Jan
  • 42,290
  • 8
  • 54
  • 79
1

That is because \w also matches \d

You can match word characters without matching a digit:

[^\W\d]{3}\d[^\W\d]{2}

Regex demo

Note that re.findall returns a list with all matches. The if statement here if re.findall(regex, p): checks if the list has a result.

If you want to match the whole string, you can use re.match.

import re
 
passwords = ['aaa5aa', 'adsfgg', 'e42dsf425']
 
regex = r'[^\W\d]{3}\d[^\W\d]{2}'
 
for p in passwords:
    if re.findall(regex, p):
        print(p)

Output

aaa5aa

If you want to match exactly 6 chars with a digit at the fourth position, you can use anchors:

^\w{3}\d\w{2}$

Regex demo

The fourth bird
  • 154,723
  • 16
  • 55
  • 70