2014-03-06 44 views
3

編寫一個程序,提示用戶輸入格式爲ddd-dd-dddd的社會安全號碼,其中d是一個數字。該程序顯示"Valid SSN"正確的社會安全號碼或"Invalid SSN"如果不正確。我幾乎擁有它,只有一個問題。社會安全號碼檢查 - Python

我不確定如何檢查格式是否正確。我可以輸入例如:

99-999-9999 

它會說它是有效的。我如何解決這個問題,這樣我只能得到"Valid SSN",如果它的格式是ddd-dd-dddd

這裏是我的代碼:

def checkSSN(): 
ssn = "" 
while not ssn: 
    ssn = str(input("Enter a Social Security Number in the format ddd-dd-dddd: ")) 
    ssn = ssn.replace("-", "") 
    if len(ssn) != 9: # checks the number of digits 
     print("Invalid SSN") 
    else: 
     print("Valid SSN") 
+0

我想它減少到一個單一的輸入。有沒有辦法做到這一點?我似乎無法得到它。 – user3105664

回答

2

如何:

SSN = raw_input("enter SSN (ddd-dd-dddd):") 
chunks = SSN.split('-') 
valid=False 
if len(chunks) ==3: 
    if len(chunks[0])==3 and len(chunks[1])==2 and len(chunks[2])==4: 
     valid=True 
print valid 
+0

非常感謝你! – user3105664

+0

這是一個非常簡單的(因此很好)實現來處理這個沒有正則表達式!祝大衛好! –

+0

@ user3105664這不檢查「d」是否是數字。如果有一些字母,這仍然會返回True。 – sashkello

8

您可以使用re匹配的模式:

In [112]: import re 

In [113]: ptn=re.compile(r'^\d\d\d-\d\d-\d\d\d\d$') 

或者r'^\d{3}-\d{2}-\d{4}$'讓儘可能@Blender提到的模式很多可讀。

In [114]: bool(re.match(ptn, '999-99-1234')) 
Out[114]: True 

In [115]: bool(re.match(ptn, '99-999-1234')) 
Out[115]: False 

從文檔:

'^' 
(Caret.) Matches the start of the string, and in MULTILINE mode also matches immediately after each newline. 
'$' 
Matches the end of the string or just before the newline at the end of the string 

\d 
When the UNICODE flag is not specified, matches any decimal digit; this is equivalent to the set [0-9]. 
+3

'^ \ d {3} - \ d {2} - \ d {4} $'可能會更容易閱讀。 – Blender

+0

@Blender thx提及,更新;) – zhangxaochen

2

不使用正則表達式我建議一個簡單的方法:

def checkSSN(ssn): 
    ssn = ssn.split("-") 
    if map(len, ssn) != [3,2,4]: 
     return False 
    elif any(not x.isdigit() for x in ssn): 
     return False 
    return True 

雙內膽與萬物收攏在一起的:

def checkSSN(ssn): 
    ssn = ssn.split("-") 
    return map(len,ssn) == [3,2,4] and all(x.isdigit() for x in ssn) 

注意:如果你重新使用Python 3,您需要將地圖轉換爲列表:list(map(...))

+0

你可以通過在你的case語句之前設置一些返回變量爲False來簡化你的代碼,然後只有在所有條件都被接受時纔將它設置爲true。引用我對這種模式的回答:除了你們更優雅地使用「地圖」調用,我們基本上採取了相同的策略。同樣作爲一般的經驗法則,您應該避免在單個函數中使用多個'return'語句。 –

+0

@DavidMarx真的,交配。儘管沒有把我的答案編輯成幾乎完全是你的答案的理由。我的目的是通過邏輯指導OP的一種清晰的逐行方式,而不是寫一段漂亮的代碼:) – sashkello

+1

你需要第一個條件'len(ssn)!= 3'嗎?看起來它可以被'map(len,ssn)!= [3,2,4]'條件覆蓋。 – pandubear