Python 我不知道';我不明白积极的前瞻(?=)是如何运作的
我将向您展示我相信正则表达式在具体程序中是如何工作的,您可能已经在这里看到了:Python 我不知道';我不明白积极的前瞻(?=)是如何运作的,python,regex,Python,Regex,我将向您展示我相信正则表达式在具体程序中是如何工作的,您可能已经在这里看到了: # strongPassword.py # Strong Password Detection # Write a function that uses regular expressions to make sure # the password string it is passed is strong. A strong password # is defined as one that is at leas
# strongPassword.py
# Strong Password Detection
# Write a function that uses regular expressions to make sure
# the password string it is passed is strong. A strong password
# is defined as one that is at least eight characters long,
# contains both uppercase and lowercase characters, and has
# at least one digit. You may need to test the string against
# multiple regex patterns to validate its strength.
import pyperclip, re
passwordRegex = re.compile(r'''(
^(?=.*[A-Z].*[A-Z]) # at least two capital letters
(?=.*[!@#$&*]) # at least one of these special characters
(?=.*[0-9].*[0-9]) # at least two numeric digits
(?=.*[a-z].*[a-z].*[a-z]) # at least three lower case letters
.{10,} # at least 10 total digits
$
)''', re.VERBOSE)
def userInputPasswordCheck():
ppass = input("Enter a potential password: ")
mo = passwordRegex.search(ppass)
if (not mo):
print("Not strong, bling blong")
return False
else:
print("Long, Strong, and down to get the crypto on")
return True
userInputPasswordCheck()
假设给定的字符串是'Azb@Ag2!H3'
如果字符串的前两个字符或其之间的任何位置后跟两个大写字母,则匹配字符串的第一部分(因为*
)。因为它只匹配正则表达式这部分之前的内容,所以字符串在这里只匹配任何内容。我前面提到的东西是匹配的,如果后面跟任意数量的字符(包括零),然后是以下字符之一:@#$&*代码>。这基本上意味着,由于at符号位于正则表达式第一部分的第一个必需大写字母之后和最后一个必需大写字母之前,因此它甚至不会计数,除非上述符号中的另一个符号出现在两个大写字母之后,否则字符串将不匹配。这不是程序应该做的;如果字符串周围有一个符号,则它应与字符串匹配;不仅仅是在一个特定的字符或字符数之后,对吗
没有必要继续分析程序是如何运行的,因为您看到了模式。这就是我没有提到的正则表达式其他部分的问题
问题是:我这里有什么不对吗?我在stack overflow和其他站点上阅读了多个源代码,但都没有用。我仍在挣扎,感觉自己不理解代码的内在工作原理
也许这个项目必须以另一种我不知道的方式完成
后续问题:如何修改此代码(特别是regex对象),使其匹配的不是满足代码中给出的所有要求的最小10个字符长的字符串,而是一个由这些要求预先指定的字符串(至少两个大写字母、三个非大写字母、两个数字和一个特殊字符),如果满足所有要求,则只返回后面的10+个字符,而在返回字符串时忽略先行断言
这基本上意味着,由于at符号位于正则表达式第一部分的第一个必需大写字母之后和最后一个必需大写字母之前,因此它甚至不计算在内
根据您的描述,您似乎将正则表达式理解为“查找两个大写字母,然后在它们之后查找一个特殊字符,依此类推”。但这里的情况并非如此
带有?=
的部分被称为“正向注视头部”,它们检查封闭模式是否匹配从当前位置开始的字符串(在本例中为字符串^
的开头),而不实际推进字符串中的位置。换句话说:
^
:字符串的开头
(?=.[A-Z].[A-Z])
:检查余数是否有两个大写字母,然后返回开始1)
(?=.[!@$&*])
:检查余数中是否有特殊字符,然后返回开始
(?=.[0-9].[0-9])
:检查余数中的数字,然后返回开始
(?=.[a-z].[a-z].[a-z])
:检查余数是否有三个小写字母,返回到开始处
{10,}
:任意十个或更多字符(这次不返回开始)
$
:字符串结尾
考虑到您的示例'Azb@Ag2!H3'
,或^Azb@Ag2!H3$
,添加了^
和$
。正则表达式匹配器的“游标”从^
开始,并立即开始第一个前瞻,将其与前缀Azb@A
,但由于它是向前看的,因此光标不会在第二个a
处结束,而是返回到^
。接下来,它匹配前缀Azb@
,并返回^
,然后返回Azb@Ag2!H3
和Azb@Ag
。现在光标第六次回到^
,并最终将{10,}
与Azb@Ag2!H3
。现在光标位于$
处,匹配完成
如果这还不清楚的话,也许多举一些例子会有所帮助
您还可以将Regex和示例字符串粘贴到或类似页面中,阅读其中生成的特定于Regex的解释,并尝试更改表达式的某些部分
1) 实际上,“返回到前视之前的位置”,在本例中是start^
?=
是一个(正的)前视,即它基本上表示“从字符串的开头开始^
,检查字符串的其余部分是否有两个大写字母(第一个(?=…)
),然后返回并检查其余字符串是否匹配,这个,这个,还有这个(其他lookaheads)这里有什么问题?“因为它只匹配正则表达式这部分之前的内容,所以字符串在这里只匹配任何内容。“–你把这和“回头看”混淆了吗?这就是lookbehind会做的,但这是lookbehind,它与这一部分后面的内容相匹配。等等,你刚才是否完全修改了这个问题,使其意思完全不同?不要那样做!正在回滚到旧版本。如果你有一个新问题,问一个新问题。他们禁止了我,根据我收到的信息,这里的禁令将永远持续,除非你通过编辑现有问题来改进它们,并通过这些修改后的问题获得更好的声誉。我只是得到了一个额外的否决票,所以我想这没有帮助…整个括号不是意味着“匹配一个字符串,如果它前面有这个”吗?我真的不明白,如果它真的在每次积极的前瞻之后回到开始,那么在每次前瞻之后会出现哪个字符串?十个以上字符(.{10,})?但是,字符串永远不会有10个字符,对吗?