2015-04-27 104 views
0

我有一個Python程序,根據正則表達式peattern搜索有效的電話號碼文件。然後,如果它發現匹配,則將該數字解析並將其打印在屏幕上。如果有擴展名,我想修改它以識別擴展名。我添加了第二種模式(patStringExten),但我不確定如何使其解析出擴展名。任何幫助,將不勝感激!Python中的正則表達式搜索

import sys 
import re 

DEF_A_CODE = "None" 

def usage() : 
     print "Usage:" 
     print "\t" + sys.argv[0] + " [<file>]" 

def searchFile(fileName, pattern) : 

     fh = open(fileName, "r") 

     for l in fh : 
       l = l.strip() 

         # Here's the actual search 
       match = pattern.search(l) 

       if match : 
         nr = match.groups() 
           # Note, from the pattern, that 0 may be null, but 1 and 2 must exist 
         if not nr[0] : 
           aCode = DEF_A_CODE 
         else : 
           aCode = nr[0] 
         print "area code: " + aCode + \ 
             ", exchange: " + nr[1] + ", trunk: " + nr[2]+ ", extension: " + nr[3] 
       else : 
         print "NO MATCH: " + l 

     fh.close() 

def main() : 

       # stick filename 
     if len(sys.argv) < 2 : # no file name 
      # assume telNrs.txt 
       fileName = "telNrs.txt" 
     else : 
       fileName = sys.argv[1] 


       # for legibility, Python supplies a 'verbose' pattern 
       #    requires a special flag 
     #patString = '(\d{3})*[ .\-)]*(\d{3})[ .\-]*(\d{4})' 

     patString = r''' 
                   # don't match beginning of string (takes care of 1-) 
       (\d{3})?    # area code (3 digits) (optional) 
       [ .\-)]*    # optional separator (any # of space, dash, or dot, 
                   # or closing ')') 
       (\d{3})     # exchange, 3 digits 
       [ .\-]*     # optional separator (any # of space, dash, or dot) 
       (\d{4})     # number, 4 digits 
       ''' 
     patStringExten = r''' 
                   # don't match beginning of string (takes care of 1-) 
       (\d{3})?    # area code (3 digits) (optional) 
       [ .\-)]*    # optional separator (any # of space, dash, or dot, 
                   # or closing ')') 
       (\d{3})     # exchange, 3 digits 
       [ .\-]*     # optional separator (any # of space, dash, or dot) 
       (\d{4})     # number, 4 digits 
       [ .\-x]* 
       [0-9]{1,4} 
       ''' 




     # Here is what the pattern would look like as a regular pattern: 
     #patString = r'(\d{3})\D*(\d{3})\D*(\d{4})' 


     # Instead of creating a temporary object each time, we will compile this 
     #    regexp once, and store this object 

     pattern = re.compile(patString, re.VERBOSE) 

     searchFile(fileName, pattern) 

main() 
+0

你在這裏問什麼?如何用'patStringExten'而不是'patString'調用'searchFile'?如何調用兩次,每次調用一次?如何將兩者合併成接受任一版本的單一模式?如何將比賽分成可以通過姓名或號碼拉出的組? – abarnert

+0

接受任一版本的模式是什麼?如果有擴展名,我將如何打印出擴展名? – Albert

回答

1

我不確定你在問什麼,但我會猜測。

首先,您的代碼忽略了您創建的新模式。如果你想實際使用,而不是patString圖案patStringExten模式,你必須把它傳遞給compile電話:

pattern = re.compile(patStringExten, re.VERBOSE) 

但是,如果你這樣做,比賽仍然只有3組,而不是4.爲什麼?因爲你沒有在分機上放置分組括號。要解決該問題,只需將它們放入:將[0-9]{1,4}更改爲([0-9]{1,4})

與此同時,現在你只有匹配的電話號碼與擴展名,不是有和沒有。你當然可以通過循環這兩個模式來解決這個問題,併爲每個模式做同樣的事情,但是最好將它們合併成一個模式,通過使最後一個組成爲可選。 (您可能想要製作最後兩行,而不僅僅是最後一組,可選...但由於倒數第二行已經是0或更多的匹配,所以無論哪種方式都是相同的。)因此,請將([0-9]{1,4})更改爲([0-9]{1,4})?

現在你groups將有4個元素,而不是3,所以現有的代碼,試圖打印nr[3]將打印擴展(或None如果可選的部分缺失),而不是拋出一個IndexError

但實際上,用字符串格式重寫輸出可能更乾淨。例如:

if nr[3]: 
    print "area code: {}, exchange: {}, trunk: {}, ext: {}".format(
     aCode, nr[1], nr[2], nr[3]) 
else: 
    print "area code: {}, exchange: {}, trunk: {}".format(
     aCode, nr[1], nr[2]) 

而不是顯示的代碼放在一起,整個事情,看在Debuggex的模式似乎更加有用,所以你可以看到它是如何工作的可視化(嘗試針對不同的字符串,使確保它符合你想要的方式,你想要的一切):

     # don't match beginning of string (takes care of 1-) 
(\d{3})?    # area code (3 digits) (optional) 
[ .\-)]*    # optional separator (any # of space, dash, or dot, 
               # or closing ')') 
(\d{3})     # exchange, 3 digits 
[ .\-]*     # optional separator (any # of space, dash, or dot) 
(\d{4})     # number, 4 digits 
[ .\-x]* 
([0-9]{1,4})? 

Regular expression visualization

Debuggex Demo

+0

這正是我需要的!謝謝!還有一件事,在「打印」區域代碼中:「+ aCode + \ 」,exchange:「+ nr [1] +」,trunk:「+ nr [2] +」,擴展名:「+ nr [3] '線,如果有擴展名,我如何才能打印擴展名? – Albert

+0

@Albert:你已經寫過那部分:'「,擴展名是:」+ nr [3]'。如果你不打印它,而不是打印'None',你可以'如果nr [3]:(整行)else:(沒有最後一部分)'。 – abarnert

+0

謝謝!我做了調整,但由於某種原因它說它不能連接在這一行上:'else: aCode = nr [0] print「area code:」+ aCode + \ 「,exchange:」+ nr [1 ] +「,trunk:」+ nr [2]' 有什麼理由? – Albert