2015-09-04 3 views
0

У меня динамический текст, который выглядит примерно такТекст Зачистка с помощью Python: Regex

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

Это не очень хорошая работа для регулярных выражений, так как компоненты, которые вы хотите разобрать вне ввода, могут отображаться в любом порядке и любом количестве.

Рассмотрите возможность использования библиотеки лексинга и синтаксического анализа, такой как грамматика выражения синтаксического анализа 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