Hi I am getting started with regex and I am already facing a problem with finding solutionto write a code that accepts password using lookbehind Assertion...
`import re
e = re.compile(r"[A-Za-z\d]((?<=[A-Z]).*)((?<=[a-z]).*)((?<=\d).*)")
while(True):
while(True):
password= input("Enter Password: ")
print(password)
result = e.search(password)
print(result)
if result is not None:
print("Correct")
break
print("False")`
It accept any input if I enter A password that starts with an Uppercase caracter followed by lowercase caracter and one digit. However, it refuses Any password that starts with a digit. My question: is there an order pattern that i should follow while using lookbehind assertions ?
CodePudding user response:
If you want to match passwords like 1Hello
and 1hEllo
like you described, you could go for just
e = re.compile(r"\w ")
for passwords with at least one character or with
e = re.compile(r"\w{8}\w*")
for passwords of length >= 8
\w
stands for any alphanumeric character (documentation)
CodePudding user response:
I would find it strange for any teacher to demand lookbehind in this case.
The most obvious approach is lookahead:
^(?=.*[A-Z])(?=.*[a-z])(?=.*\d).{6,}
You can even do it without lookaround, but then you'd better make it a negative test (i.e. a regex matching the invalid passwords rather than the valid ones).
^(.{,5}|[^A-Z]*|[^a-z]*|\D*)$
So what about lookbehind? I could try and reverse my initial attempt:
.{6,}(?<=[A-Z].*)(?<=[a-z].*)(?<=\d.*)$
This works in JavaScript, but not in Python: Python's regex engine demands fixed-width lookbehind.
Oh sure, I could introduce a lookbehind. There you go.
^(?=.*[A-Z])(?=.*[a-z])(?=.*\d).{6,}(?<=...)
But it serves no purpose. I'm just adding lookbehind for the sake of having lookbehind in my regex; not because it brings any benefit.
I've always considered lookbehind to be my last resort, in case everything else fails or results in a ridiculously big regex. Here, that is definitely not the case.