python利用正则筛选信用卡

本文来源于两个简单的题目:

  1. 判断一对单词是否是" Anagrams "
  2. 判断信用卡是否合理

判断 Anagrams

anagrams 的百度翻译:由颠倒字母顺序而构成的字(短语)

而题目给出例子:

[ DOG , ODG ]
[ DOG , DOG ]
[ DOG , GOD ]
[ DOG , GDO ]

均为 anagrams 。
那思路就简单了,直接拆分字母,排序,比较就 ok 。

判断信用卡

题目给出的要求如下:

The criteria are:
• It must start with a 4,5 or 6
• It must be exactly 16 digits
• It must be numbers only
• It can have a digits in groups of 4, separated by one hyphen “-“
• It should not contain any other characters.
• It must NOT have any 4 repeated digits.

样例输出如下:

378282246310005 Invalid
30569309025904 Invalid
6011111111111117 Invalid
5123-2332-3232-3213 valid

py文件

两个题目合并在一个 py 文件中。 
而入参数分别是两个文件的名字,一个是 anagram.txt ,另一个是 credit_cards.txt ,他们分别长这样:

python利用正则筛选信用卡_第1张图片

在这里插入图片描述

最后的程序长这样:

#! /usr/bin/python3
import re
###############################
##You need to implet the following methods:
##
##Question 1
##anagram_validator()  
##
##Question 2
##credit_card_validator()  

################################

###################################################
# Question 1: Check for anagrams:#
###################################################

def get_list(src_str):
    sub_list=[]
    word_tmp=''
    for word in src_str:
        if word != ',':
           word_tmp = word_tmp+word
        else:   
           sub_list.append(word_tmp)
           word_tmp = ''
    return sub_list

def read_anagram(file_name):
    '''
    Input: a file name
    Return: a nested list of two words list
    Example : [[word1,word2],[word3,word4]...etc]
    '''
    with open(file_name,encoding = 'utf-8') as f:
        return_list =[]        
        file_conment = f.read()

    file_conment_new = re.sub(r'\n',',',file_conment)
    file_conment_new = file_conment_new+','
    subs_list = get_list(file_conment_new)
    i=0
    while i < (len(subs_list)-1):
        return_list.append([subs_list[i],subs_list[i+1]])
        i=i+2  
    return return_list



def anagram_validator(anagram):
    '''
    Input is the output from "read_anagram()".
    Return: list of "anagrams" or "Not anagrams" values for each two words
    example input (dog,gdo),(try,elm) then output would be ["anagrams","Not anagrams"] with sequence of the input
    '''
    result_list=[]
    for i in range(len(anagram)):
        word_font = ''.join((lambda x:(x.sort(),x)[1])(list(anagram[i][0])))
        word_back = ''.join((lambda x:(x.sort(),x)[1])(list(anagram[i][1])))
        if word_font == word_back:
            result_list.append('Anagrams')
        else:
            result_list.append('Not anagrams')

    return result_list

############################################
# Question 2: Validate credit cards         #
############################################
def read_credit_cards(file_name):
    '''
    Input: a file name
    Return tuple of numbers
    '''
    with open(file_name,encoding='utf-8') as f:
        card_conment = f.read()

    card_conment = re.sub(r'\[','',card_conment)
    card_conment = re.sub(r'\]','',card_conment)
    card_conment = card_conment+','
    card_list = get_list(card_conment)
    return tuple(card_list)


def credit_card_validator(numbers):
    '''
    Input: tuple of numbers
    Return:dictionary of credit card numbers where key is the number and value if valid or invalid
    '''
    validator_list=[]
    credit_dict={}
    for i in range(len(numbers)):
        validator_list.append(numbers[i])
    
    for i in range(len(numbers)):
        ch_num = 0
        repeat_flag = 0
        for ch in validator_list[i]:
            if  ord("A")<=ord(ch)<=ord("Z"):
                ch_num+=1
                break

        tmp_list = []
        tmp_list = (re.sub(r"[^\d]", "", validator_list[i]))
        for index in range(len(tmp_list)-4):
            if(tmp_list[index] == tmp_list[index+1] and
                tmp_list[index] == tmp_list[index+2] and
                tmp_list[index] == tmp_list[index+3] ):
                repeat_flag = 1
                break;

        if(validator_list[i][0] != '4' and
           validator_list[i][0] != '5' and
           validator_list[i][0] != '6' ):
           credit_dict[validator_list[i]]='Invalid'
        elif( len(re.sub(r"\D", "", validator_list[i])) != 16 ):
            credit_dict[validator_list[i]]='Invalid'
        elif(ch_num > 0):
            credit_dict[validator_list[i]]='Invalid'
        elif( 
              (re.search(r"-",validator_list[i])) and 
                    ( validator_list[i][4] != '-' or  
                        validator_list[i][9] != '-'or
                        validator_list[i][14] != '-'
                    )
            ):
            credit_dict[validator_list[i]]='Invalid'
        elif(re.search(r"[^-\d]",validator_list[i])):
            credit_dict[validator_list[i]]='Invalid'
        elif(repeat_flag == 1 ):
            credit_dict[validator_list[i]]='Invalid'
        else :
            credit_dict[validator_list[i]]='Valid'
        space_str = ''     

    return credit_dict


def print_credit_card_summary(dict_o):
    '''
    Input: dict
    Return:
        printing summary of validation result - space between credit card and status is 40 width
        example:
        378282246310005     Invalid
        30569309025904		Invalid
    ''' 
    space_str = ''       
    for key in dict_o:
        new_str = key + dict_o[key]
        if(dict_o[key] == "Valid"):
            new_str_tmp = new_str[:-5]
            space_lenth = 46-len(new_str)
            for x in range(space_lenth):
                space_str +=' '
            print(new_str_tmp + space_str + 'Valid')
            space_str=''
        else :
            new_str_tmp = new_str[:-7]
            space_lenth = 48-len(new_str)
            for x in range(space_lenth):
                space_str +=' '
            print(new_str_tmp + space_str + 'Invalid')
            space_str='' 



####### THE CODE BELOW IS FOR TESTING###################
############### DO NOT  CHANGE #########################


import sys

if __name__ == '__main__':
    # Take care of the console inputs
    if len(sys.argv) <= 1:
        sys.argv = ['', "anagram.txt", "credit_cards.txt"]
    stars = '*' * 40
    print(stars)
    print("Testing Question 1 --- Anagrams?")
    print(stars)

    # testing reading_anagrams
    try:
        anagram = read_anagram(sys.argv[1])
        if not anagram:
            print("read_anagram() returns None.")
        else:
            print("anagram: ", anagram)
            print()
    except Exception as e:
        print("Error (readnumbers()): ", e)

    # testing anagram_validator
    Anagrams = 0
    NAnagrams = 0
    try:
        if not anagram:  # Question 1 has not been implemented
            print("anagram_validator() skipped....")
        else:
            result = anagram_validator(anagram)
            if result == None:
                print("anagram_validator() returns None.")
            else:
                for i in result:
                    if i == "Anagrams":
                        Anagrams += 1
                    elif i == "Not anagrams":
                        NAnagrams += 1
                print("Number of valid Anagrams is {} and Not anagrams is {}.".format(Anagrams, NAnagrams))

    except Exception as e:
        print("Error (anagram_validator()):", e)

    # testing  Question 2
 
    print("\n\n" + stars)
    print("Testing Question 2 --- Credit Card Validator")
    print(stars)

    # Testing reading_credit_cards
    try:
        tup = read_credit_cards(sys.argv[2])
        if not tup:
            print("read_credit_cards() returns None.")
        else:
            print("The tuple of credit_cards: {}".format(tup))
    except Exception as e:
        print("Error (read_credit_cards()):", e)

    # Testing credit_card_validator
    vcc = 0
    ivcc = 0
    try:
        if not tup:  # Readin_Question 2 has not been implemented
            print("credit_card_validator() skipped...")
        else:
            cc_dict = credit_card_validator(tup)
            tmp_cc_dict = cc_dict
            if not cc_dict:
                print("credit_card_validator()  returns None.")
            else:
                for items in cc_dict.keys():
                    if cc_dict[items] == "Valid":
                        vcc += 1
                    elif cc_dict[items] == "Invalid":
                        ivcc += 1
                print("Number of valid credit cards is {} and invalid {}.".format(vcc, ivcc))
    except Exception as e:
        print("Error (credit_card_validator()):", e)

    # testing  Question 2
    print("\n\n" + stars)
    print("Testing Question 2b --- Print Credit Card Summary")
    print(stars)
    # Testing print_credit_card_summary
    try:
        if not tmp_cc_dict:  # Dict credit card output has not been implemented
            print("print_credit_card_summary() skipped...")
        else:
            import io  # do not delete this line
            from contextlib import redirect_stdout  # do not delete this line

            f = io.StringIO()
            with redirect_stdout(f):
                print_credit_card_summary(tmp_cc_dict)
                out = f.getvalue()
            if not out:
                print("print_credit_card_summary()  returns None.")
            else:
                count44 = 0
                count46 = 0
                for line in out.splitlines():
                    if len(line) - len(line.split()) == 44:
                        count44 += 1
                    elif len(line) - len(line.split()) == 46:
                        count46 += 1
                if count44 == vcc and count46 == ivcc:
                    print("Your format looks good")
                else:
                    print("You might have some issues in your summary format")


    except Exception as e:
        print("Error (print_credit_card_summary()):", e)


你可能感兴趣的:(python)