这个正则表达式为什么不按预期工作?

问题描述:

我需要一个正则表达式模式来捕捉任何16位数字的字符串(每个四个数字组用连字符分隔),没有任何数字重复超过3次,中间或者没有连字符。这个正则表达式为什么不按预期工作?

所以我写的模式是

a=re.compile(r'(?!(\d)\-?\1\-?\1\-?\1)(^d{4}\-?\d{4}\-?\d{4}\-?\d{4}$)') 

但例如“5133-3367-8912-3456”当3重复4次变得更加匹配。 (负向预览部分有什么问题?)

+0

你需要使用正则表达式吗?看起来这样使用'str.split'和'collections.Counter'编写和理解会更容易。 – jonrsharpe

预览只能在他们所在的位置进行检查,所以在你的情况下在字符串的开始。如果您希望向前看基本检查整个字符串,如果某种模式可以匹配或不匹配,您可以在前面添加.*以使字符串更深入。

对于您的情况,您可以将其更改为r'(?!.*(\d)\-?\1\-?\1\-?\1)(^d{4}\-?\d{4}\-?\d{4}\-?\d{4}$)'

也没有必要逃避他们在的位置减去,我会移动^后的前瞻。我不知道python正则表达式是如何优化的,但是这样一来,字符串锚点的起始位置首先匹配(仅有1个有效位置),而不是在任何地方检查前瞻,只是在^处匹配失败。这会给r'^(?!.*(\d)-?\1-?\1-?\1)(\d{4}-?\d{4}-?\d{4}-?\d{4}$)'

+0

@ RizwanM.Tuman这是一个有效的匹配并得到匹配,请参阅https://regex101.com/r/CYA4ng/1。不确定你为什么怀疑它? –

+0

我碰巧被误解了这个问题......并且我把责任归咎于操作系统的帖子中的混淆;) –