2015-09-04 84 views
0

我有一個看起來像這樣文字刮痧:正則表達式

my_text = "address ae fae daq ad, 1231 asdas landline 213121233 -123 mobile 513121233 cell (132) -142-3127 
      email [email protected] , sdasd [email protected] - [email protected]" 

文本開頭的「地址」動態文本。只要我們看到「地址」,我們就需要從那裏颳去所有的東西,直到出現「固定電話」/「移動」/「小區」。從那裏開始,我們希望在所有電話文本(不改變兩者之間的空格)的情況下進行刮擦。我們從第一次出現「固定電話」/「移動」/「小區」開始,並在我們發現「電子郵件」時立即停止。 終於我們颳了電子郵件部分(不改變之間的空間)

'座機'/'移動'/'細胞'可以以任何順序出現,有時可能不會出現。例如,文本也可能看起來像這樣。

my_text = "address ae fae daq ad, 1231 asdas 
      cell (132) -142-3127 landline 213121233 -123  
      email [email protected] , sdasd [email protected] - [email protected]" 

還有一些工程需要完成,以形成包含在地址,電話和電子郵件文本中的子文本數組。 地址的子文本總是用逗號(,)分隔。 電子郵件的子文本可以用逗號(,)或連字符( - )分隔。

我的輸出應該是一個JSON字典看起來是這樣的:

resultant_dict = { 
         addresses: [ 
            { address: "ae fae daq ad" } 
           , { address: "1231 asdas" } 
           ] 
        , phones: [ 
            { number: "213121233 -123", kind: "landline" } 
           , { number: "513121233", kind: "mobile" } 
           , { number: "(132 -142-3127", kind: "cell" } 
          ] 
        , emails: [ 
            { email: "[email protected]", connector: "" } 
           , { email: "sdasd [email protected]", connector: "," } 
           , { email: "[email protected]", connector: "-" } 
           ] 
} 

我想實現使用正則表達式或Python中的任何其他辦法的事情。我不知道如何寫這個,因爲我是一個新手程序員。

回答

1

這隻要沒有空格的工作在你的電子郵件

import re 
my_text = 'address ae fae daq ad, 1231 asdas landline 213121233 -123 mobile 513121233 cell (132) -142-3127 email [email protected] , [email protected] - [email protected]' 

split_words = ['address', 'landline', 'mobile', 'cell', 'email'] 
resultant_dict = {'addresses': [], 'phones': [], 'emails': []} 

for sw in split_words: 

    text = filter(None, my_text.split(sw)) 
    text = text[0].strip() if len(text) < 2 else text[1].strip() 
    next_split = [x.strip() for x in text.split() if x.strip() in split_words] 

    if next_split: 
     text = text.split(next_split[0])[0].strip() 

    if sw in ['address']: 
     text = text.split(',') 
     for t in text: 
      resultant_dict['addresses'].append({'address': t.strip()}) 

    elif sw in ['landline', 'mobile', 'cell']: 
     resultant_dict['phones'].append({'number': text, 'kind': sw}) 

    elif sw in ['email']: 

     connectors = [',', '-'] 
     emails = re.split('|'.join(connectors), text) 
     text = filter(None, [x.strip() for x in text.split()]) 

     for email in emails: 

      email = email.strip() 
      connector = '' 
      index = text.index(email) if email in text else 0 

      if index > 0: 
       connector = text[index - 1] 

      resultant_dict['emails'].append({'email': email, 'connector': connector}) 

print resultant_dict 
+0

好的。這很好。但是我想保留空間,這是有原因的。我將嘗試相應地編輯代碼並進行更新。 – user3422637

+0

如果你想出一個快速調整來包含空格,你可以添加它:) – user3422637

1

這對於正則表達式來說不是一件好事,因爲您想要從輸入中解析出的組件可以以任何順序和任意數量出現。

考慮使用lexing和解析庫,如pyPEG解析表達式語法。

另一種方法是使用str.split()re.split()將輸入文本拆分爲令牌。然後掃描那些尋找關鍵字的令牌,如address,cell,,累積以下令牌,直到下一個關鍵字。這種方法讓split()執行標記化工作的第一部分,讓您通過手動完成其他詞法工作(通過識別關鍵字)和解析工作。

手動方法更具啓發性,但更加冗長且不夠靈活。它是這樣的:

text = """address ae fae daq ad, 1231 asdas 
      cell (132) -142-3127 landline 213121233 -123  
      email [email protected] , sdasd [email protected] - [email protected]""" 

class Scraper: 
    def __init__(self): 
     self.current = [] 
     self.current_type = None 

    def emit(self): 
     if self.current: 
      # TODO: Add the new item to a dictionary. 
      # Later, translate the dictionary to JSON format. 
      print(self.current_type, self.current) 

    def scrape(self, input_text): 
     tokens = input_text.split() 
     for token in tokens: 
      if token in ('address', 'cell', 'landline', 'email'): 
       self.emit() 
       self.current = [] 
       self.current_type = token 
      else: 
       self.current.append(token) 
     self.emit() 

s = Scraper() 
s.scrape(text) 

這發出:

address ['ae', 'fae', 'daq', 'ad,', '1231', 'asdas'] 
cell ['(132)', '-142-3127'] 
landline ['213121233', '-123'] 
email ['[email protected]', ',', 'sdasd', '[email protected]', '-', '[email protected]'] 

你要使用re.split()使它分裂成'ad,'['ad', ','],添加代碼來處理令牌像,,並使用庫將字典轉換爲JSON格式。

+0

感謝。你能否使用正則表達式以外的任何其他方式提供工作解決方案? – user3422637

+0

完成。 **注意:**程序處理像'ad'這樣的案例越複雜,pyPEG就越好。這個答案越複雜,它會給你和其他讀者的指導意義越小。還要注意輸入解析代碼'parse()'與輸出構造代碼'emit()'是如何分離的。這種模塊化使得它更易於理解,調試和修改。 – Jerry101