【问题标题】:Why doesn't this regex pattern work as intended?为什么这个正则表达式模式不能按预期工作?
【发布时间】:2017-09-04 09:08:18
【问题描述】:

我需要一个正则表达式模式来捕获任何 16 位数字字符串(每组由连字符分隔的四个数字组),而任何数字都不会重复超过 3 次,中间有或没有连字符。

所以我写的模式是

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

但即使 3 重复 4 次,示例“5133-3367-8912-3456”也会匹配。 (负前瞻部分有什么问题?)

【问题讨论】:

  • 你需要使用正则表达式吗?使用str.splitcollections.Counter 似乎更容易编写和理解。

标签: python regex python-3.x credit-card


【解决方案1】:

Lookaheads 仅在它们所在的位置进行检查,因此在您的情况下是在字符串的开头。如果您想先行检查整个字符串,如果某个模式可以匹配或不匹配,您可以在前面添加.*,以便更深入地了解字符串。

在您的情况下,您可以将其更改为 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}$)'

【讨论】:

  • @RizwanM.Tuman 这是一个有效的匹配并且得到匹配,见regex101.com/r/CYA4ng/1。不知道你为什么怀疑它?
  • 我碰巧被误解了这个问题......我将这一点归咎于操作员帖子中的混乱;)
猜你喜欢
  • 1970-01-01
  • 2022-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多