python - 使用正则表达式 python 验证卡号

标签 python regex

我有一些信用卡号,想根据以下规则验证它们。

► 只能由数字(0-9)组成

► 它可以有 4 个一组的数字,用一个连字符“-”分隔

► 它不能有 4 个或更多连续的重复数字

► 它可能只包含没有空格的数字

输入:

  • 5123-4567-8912-3456

  • 61234-567-8912-3456

  • 4123356789123456

  • 5133-3367-8912-3456

输出:

  • 有效

  • 无效(因为卡号没有分成4等份)

  • 有效

  • 无效(连续33个33位重复4次)

我已经尝试过 here,只有在末尾包含连字符时它才有效。有人可以给我一个正确的正则表达式吗。

编辑:

正则表达式代码:([0-9]{4}-){4}

要匹配的输入6244-5567-8912-3458

它不匹配,直到我在末尾加上连字符。

编辑

import re
import itertools
text="5133-3367-8912-3456"
print(len(text))

l=[(k, sum(1 for i in g)) for k,g in itertools.groupby(text)]  #To calculate frequency of characters and later we can filter it with the condition v<=3 for checking the concurrency condition

if re.search(r'^[456]+',text) and len(text)==16  and re.search(r'[\d]',text) and all(v<=3 for k,v in l) and bool(re.search(r'\s',text)) is False and bool(re.search(r'[a-z]',text)) is False or( bool(re.search(r'-',text))is True and len(text)==19) :
    print("it passed")

else :
    print("False")

最佳答案

我的解决方案有两步逻辑。你不能一次性做到这一点的原因与 python 的限制有关。我们将保存它以备后用。如果您有兴趣,请查看附录 1

2步:第一步检查'-'是否在正确的位置,第二步检查是否有4个连续相等的数字。

我将从第 2 步开始,这是最耗内存的步骤:检查是否没有连续的 4 个数字的正则表达式。以下正则表达式将执行:

((\d)(?!\2{3})){16}

解释:

(                       # group 1 start
  (\d)                  # group 2: match a digit
  (?!\2{3})             # negative lookahead: not 3 times group 2
){16}                   # repeat that 16 times.

看看example 1

第一步是匹配 4 位数字组,最终由“-”分隔(查看 example 2)这里要解决的问题是确保如果第一组和第二组数字由“-”分隔,那么所有组都需要用“-”分隔。我们设法通过在下一个正则表达式中使用对第 2 组的反向引用来做到这一点。

(\d{4})(-?)(\d{4})(\2\d{4}){2}

解释:

(\d{4})                 # starting 4 digits
(-?)                    # group 2 contains a '-' or not
(\d{4})                 # 2nd group of 4 digits
(\2\d{4}){2}            # last 2 groups, starting with a backreference
                        # to group 2 ( a '-' or not)

示例程序:

 import re

 pattern1 = r"(\d{4})(-?)(\d{4})(\2\d{4}){2}"
 pattern2 = r"((\d)(?!\2{3})){16}"

 tests = ["5123-4567-8912-3456"]

 for elt in tests:
     if re.match( pattern1, elt):
         print "example has dashes in correct place"
         elt = elt.replace("-", "")
         if re.match(pattern2, elt):
             print "...and has the right numbers."

附录: 现在是沙漠。我把一个正则表达式放在一起一次性完成。让我们根据每个数字在组中的位置来考虑每个数字需要什么:

  • 第一个数字:后跟 3 个数字
  • 第二位数字:后接 3 位数字或数字、数字、破折号、数字
  • 第 3 位数字:后跟 3 位数字或数字、破折号、数字、数字
  • 第 4 位数字:后接 3 位数字或破折号、数字、数字、数字

因此,对于我们在示例 1 中使用的前瞻性,我们需要为每个数字呈现后续的所有可能性。让我们看一下一组 4 位数字的模式:

(
  (\d)             # the digit at hand
  (?!              # negative lookahead
   \2{3}           # digit, digit, digit
  |\2{2}-\2        # OR digit, digit, dash, digit
  |\2-\2{2}        # OR digit, dash, digit, digit
  |-\2{3}          # OR dash, digit, digit, digit
  )
){4}               # 4 times, for each digit in a group of 4

当然,我们希望将其扩展到 16 位数字。我们需要定义是否可以在数字前添加“-”。一个简单的 -? 是行不通的,因为信用卡不是以破折号开头的。让我们使用交替:

(?                 # if
  (?<=\d{4})       # lookbehind: there are 4 preceding digits
  -?               # then: '-' or not
  |                # else: nothing
)

结合起来,这使我们:

\b((?(?<=\d{4})-?|)(\d)(?!\2{3}|\2{2}-\2|\2-\2{2}|-\2{3})){16}\b

看看 example 3 。我们需要两边都有\b,因为我们想确保无论何时匹配成功,它都匹配 complete 字符串。

公平地说:如果这是要走的路,人们会怀疑。从好的方面来说,我们现在有一个分两步完成的正当理由:python 的标准 re 不支持条件等等。您可以通过使用替换来解决此问题。或者切换编程语言。 ;-)

附录 2: 人们问我 example 3 中的 16 来自哪里。完整的字符串不是可以有 19 个字符长吗?原因是只要内部正则表达式(第 1 组)匹配一次,它就会与 [0-9]-[0-9] 匹配。该匹配必须恰好成功 16 次。

关于python - 使用正则表达式 python 验证卡号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46079770/

相关文章:

javascript - 删除括号前后的所有空格

python - Pyparsing:语法在解析具有指数和对数函数的算术表达式时无法解析空格

python - 当我运行 python 代码时,它显示 “<< was unexpected at this time"

python - 一种更新数据并在一次尝试中再次使用更新后的数据的功能

regex - R:通过正则表达式提取字符串匹配部分的列表

java - 带或不带前导零的时间戳的正则表达式?

javascript - 在 Python 中嵌入 Node.js

python - 带有用于上传的 Flask 的 HTML 文件夹选择器

regex - Swift 和正则表达式,cpu 为某些字符串失控

regex - GWT - 2.1 RegEx 类来解析自由文本