2016-06-13 3 views
0

hi Я ищу способ извлечь заголовки заголовков (выделены полужирным шрифтом) из этого блока текста (оригинал из файла mbox) Я пробовал это регулярное выражение, которое работало над поиском расширенного поиска текста, но не работал на питона ^ \ ш + - (\ W +) - (\ W +) ?:regex - python, извлекающий имена заголовков электронной почты

rgex = re.findall('^\w+-?(\w+)?-?(\w+)?:', mail); 

ЭТО ЧТО ВНУТРИ почта

X-видимому,-To?: [email protected]; Чт, 09 июню 2016 13:41:21 +0000
Return-Path:
Received-SPF: передача (домен yahoo.com обозначает 72.30.235.45, как это разрешено отправителем)
Полученное: от 127.0.0.1 (EHLO n3-vm9.bullet.mail.bf1.yahoo.com) (72.30.235.45) по mta1287.mail.ne1.yahoo.com с SMTPS; Thu, 09 Jun
2016 13:41:21 +0000
DKIM-Подпись: v = 1; а = sha256-RSA; с = расслаблены/расслаблены; д = yahoo-inc.com; s = yibm; т = 1465479679;
Для: [email protected]
От: "Yahoo"
Reply-To: "Yahoo"
X-YMailISG: PCypxycWLDvGv4Bg8ShrtzVYi3vpFMAjYaqWyWybcVJ_ZQff eyquyqb..Qu6UKhX_Tyz5b3da2iDtRStJpVnNulZHOb8GznJQTCKk9sjvboS KsbzY4E1uScWz0Ieo0jjG0YHrB1dTCzOSeMiPNumCCFS1sR3_SkyMBGG_D2D wWtdRducxLa2YgEMMubVpMtNJMBv.bwk0 .E.jQNEy8I3LnJEqcDpmIUM7bZL XgkEFz7yl1Zo6Sj4r0z6pGlVIFOql7uG9Bwq2VJoK1Q1upKJUOBfQqzf64y2 9fXLnQsWENpZloxwncGzLhdzEYGgE3xNuFV8QFxZGXyvtKZF oykH49M03URN jtx8Yg6ypjyRbBIRVJGVFbjAvW6io3yeyIFh042jlgYQtLxbneFA60hn9ifT Mit3bQ5l7Tginw0OgRM2cbqLo0tEZFt9vlN597Z3vPGwsVdBcTp9wnk6orj2 TqjEpAmODy3Yru2HzDP7Dbwq9CGaIozUm91VNWqw5Dy7AMQEsuvnBop7Fflk G21m1WKMBgrS.2bOLQ4797E09LjlyyoWI9FouUNNhDljnPPf2AeKUKzauctw ULOQPveWAm4lDsNLMp5yvXDYNIe5HMor84SVd8_xF3Icna1PAftXGzJUHrXK NZSEN_VO0GprGfaNQg4uSW_0wXFXwC6TYQ4CMjz53o0qNGpILogVfRLwFCFL DtW8nimkLLsNzmDajzJsR_juA86Orw2NE5ED4qdpPxmyxyrXYOQPu3O6zeYf 7mBzU0aX7VHJUxJ4L3HdB9qTjbTaCdnySrnjGtd7u9Cn9yRJirDNeg3UA82P PeA1ZDfc0vKdrn5QI6e6YKa2TTt7Dspy3jObgSapH5epc3LyQVyN7yjpxrq_ MXAbpqedjUfcwq3c7lpt8xxUxy.MXWg0fJO059xijvb_sYTaQTGUWAMeVU.6 IW.hSksejwpn._CgE9Kqabbk5 qgYIdYRW1pmz5OBYh0skCX1TrFRuxbGvDit R_wr.wbTpJGiSST.b0ZetmgN72bVvlRtmNPw1Dk.zxaacXxhGSMWupPUDLJZ OMrap2ax8oiQrxT3jIhk8seIkaNJ.tGUhlPx6G4lJJaz0g89LmjBaEjGUG8P W3Phh9db3hjxUIX5UC0jg5ai2XZ7u_wXn2Muk61N1eRCZ0oA2S25YDPK1dh. 3VQ6pH8SSBxVkQHUJXbZUNqLAzi5V5wRS7oeitXERGgA2DiZB268.rJxS7di OMT5eGoITG4LnAo1M3nsVQ6xceHDd4v6KD9KfBgTHX_iLUv_skCv4dVUgVvj edKOFiOMHBTpJ9J9BECjTTzEUpc.fCNUcRwSsiSkqbRhUsAdCbxQZir3Nb1Z 6FzI6J2eNqpj4azjmDeI15R8MyN7VFc6bl6pCZySk2Tx5SQESDm.sVkADSVR pI2nuscEjU3xo_qGUxbh5mbAA17K2zYpcFXaOce8_9Eszos5pURCcdtBYUqI I_DOtvNe.zWY1ShRcr9ZzTj3ibmc7NBmvumhVMjqirb12mfJ6oxHv8d86gze HtAJmJghczUg5otSzdxSgEJJxjMZrzSidJ9FP.gPiPWtuukz82YpZ32MnCVs 6.V2DRxpUmZa31KH93QSEzwMlCn3FFTLBv9izcjoFP81yeAn.3QloF8XIC3K WmtXtloyeGjuygAhlkd_prXmMGGC5JmPlY8xu4k1NavkdDh6pG6zIkt83Wsd P.D.0BgM
X-Возникнув-IP-: [75.30.245.45]
Authentication-Results: mta1287.mail.ne1.yahoo.com от = yahoo-inc.com; domainkeys = нейтральный (no sig); от = yahoo-inc.com; DKIM = передача (ки)

+1

Ну ... Попробуйте что-то вроде [ '([^ \ s:] * \ d +: \ d +) ([^ \ s:] +): '] (https://regex101.com/r/wY3qH2/1). –

+2

Есть ли причина не просто использовать пакет 'mail' для анализа заголовков (и, следовательно, получить имена заголовков)? – donkopotamus

+0

donkopotamus- да в моем случае это должно быть из определенного файла. – user1731805

ответ

1

Более простой подход, чем разработка надлежащего регулярного выражения было бы использовать более подходящий инструмент, который поставляется с питоном ... email.parser модуля, который предназначен для разбора rcf822 таких сообщений, как это ,

>>> from email import parser 
>>> txt = """X-Apparently-To: [email protected]; Thu, 09 Jun 2016 13:41:21 +0000 
... Return-Path: 
... Received-SPF: pass (domain of yahoo.com designates 72.30.235.45 as permitted sender) 
... Received: from 127.0.0.1 (EHLO n3-vm9.bullet.mail.bf1.yahoo.com) (72.30.235.45) by mta1287.mail.ne1.yahoo.com with SMTPS; Thu, 09 Jun 2016 13:41:21 +0000 
... DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo-inc.com; s=yibm; t=1465479679; 
... To: [email protected] 
... From: "Yahoo" 
... Reply-To: "Yahoo" 
... X-YMailISG: PCypxy... 
... X-Originating-IP: [75.30.245.45] 
... Authentication-Results: mta1287.mail.ne1.yahoo.com from=yahoo-inc.com; domainkeys=neutral (no sig); from=yahoo-inc.com; dkim=pass (ok) 
... """ 
>>> msg = parser.Parser().parsestr(txt, headersonly=True) 
>>> print(msg.keys()) 
['X-Apparently-To', 'Return-Path', 'Received-SPF', 'Received', 'DKIM-Signature', 'To', 'From', 'Reply-To' 'X-YMailISG', 'X-Originating-IP', 'Authentication-Results'] 
+0

@ WiktorStribiżew, потому что я не мог быть обеспокоен загрязнением ответа следующими тремя очень большими заголовками ... – donkopotamus

+0

:) Вы могли бы урезать их, по крайней мере, это немного озадачило меня. –

+0

@ WiktorStribiżew Это лучшая идея :-) – donkopotamus

0

Если вы используете регулярное выражение над целым файлом MBox то регулярное выражение не будет работать - вы будете иметь, чтобы написать программу. Причина в том, что тело сообщения может иметь токены, которые будут точно совпадать с маркером заголовка.

Предполагая, что вы только запустить регулярное выражение над частью заголовка файла MBox (ов), а затем, глядя на email RFC то следующее регулярное выражение должно работать (раздел 2.2.):

«^ ([^:] +):»

0

Вашего '^\w+-?(\w+)?-?(\w+)?:' регулярного выражение соответствует началу строки (^), затем 1+ слово символы, а затем дополнительному -, то 1+ слова символы захватываются в дополнительном Группа 1 (и те возвращаются re.findall в качестве первого элемента в каждом кортеже, возвращенном в виде списка), а затем дополнительный дефис, снова группа захвата, соответствующая символам 1+ слов (необязательно, но все же возвращаемая как 2-й элемент в кортеже) и : в конце. Это не сработает из-за ^, опционально - между \w и 2 группами захвата.

Если ввод, который вы получаете, соответствует стилю сообщения rfc 8222, вам следует рассмотреть возможность переключения на решение from email import parser, приведенное выше.

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

r"^([^\s:]+):\s" 

и использовать он с re.findall и re.M.

Regex объяснение:

  • ^ - начало строки (как re.M делает ^ матч позиции после символа новой строки) или начало строки)
  • ([^\s:]+) - Захват группы 1 согласующих 1+ других символов чем пробелы и толстая кишка
  • : - толстый кишечник
  • \s - провисание туз.

Посмотреть regex demo

Python demo где это re.findall возвращает только захваченные тексты:

import re 
p = re.compile(r'^([^\s:]+):\s', re.MULTILINE) 
test_str = "X-Apparently-To: [email protected]; Thu, 09 Jun 2016 13:41:21 +0000 \nReturn-Path: \nReceived-SPF: pass (domain of yahoo.com designates 72.30.235.45 as permitted sender) \nReceived: from 127.0.0.1 (EHLO n3-vm9.bullet.mail.bf1.yahoo.com) (72.30.235.45) by mta1287.mail.ne1.yahoo.com with SMTPS; Thu, 09 Jun \n2016 13:41:21 +0000 \nDKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo-inc.com; s=yibm; t=1465479679; \nTo: [email protected] \nFrom: \"Yahoo\" \nReply-To: \"Yahoo\" \nX-YMailISG: PCypxycWLDvGv4Bg8ShrtzVYi3vpFMAjYaqWyWybcVJ_ZQff eyquyqb..Qu6UKhX_Tyz5b3da2iDtRStJpVnNulZHOb8GznJQTCKk9sjvboS KsbzY4E1uScWz0Ieo0jjG0YHrB1dTCzOSeMiPNumCCFS1sR3_SkyMBGG_D2D wWtdRducxLa2YgEMMubVpMtNJMBv.bwk0.E.jQNEy8I3LnJEqcDpmIUM7bZL XgkEFz7yl1Zo6Sj4r0z6pGlVIFOql7uG9Bwq2VJoK1Q1upKJUOBfQqzf64y2 9fXLnQsWENpZloxwncGzLhdzEYGgE3xNuFV8QFxZGXyvtKZFoykH49M03URN jtx8Yg6ypjyRbBIRVJGVFbjAvW6io3yeyIFh042jlgYQtLxbneFA60hn9ifT Mit3bQ5l7Tginw0OgRM2cbqLo0tEZFt9vlN597Z3vPGwsVdBcTp9wnk6orj2 TqjEpAmODy3Yru2HzDP7Dbwq9CGaIozUm91VNWqw5Dy7AMQEsuvnBop7Fflk G21m1WKMBgrS.2bOLQ4797E09LjlyyoWI9FouUNNhDljnPPf2AeKUKzauctw ULOQPveWAm4lDsNLMp5yvXDYNIe5HMor84SVd8_xF3Icna1PAftXGzJUHrXK NZSEN_VO0GprGfaNQg4uSW_0wXFXwC6TYQ4CMjz53o0qNGpILogVfRLwFCFL DtW8nimkLLsNzmDajzJsR_juA86Orw2NE5ED4qdpPxmyxyrXYOQPu3O6zeYf 7mBzU0aX7VHJUxJ4L3HdB9qTjbTaCdnySrnjGtd7u9Cn9yRJirDNeg3UA82P PeA1ZDfc0vKdrn5QI6e6YKa2TTt7Dspy3jObgSapH5epc3LyQVyN7yjpxrq_ MXAbpqedjUfcwq3c7lpt8xxUxy.MXWg0fJO059xijvb_sYTaQTGUWAMeVU.6 IW.hSksejwpn._CgE9Kqabbk5qgYIdYRW1pmz5OBYh0skCX1TrFRuxbGvDit R_wr.wbTpJGiSST.b0ZetmgN72bVvlRtmNPw1Dk.zxaacXxhGSMWupPUDLJZ OMrap2ax8oiQrxT3jIhk8seIkaNJ.tGUhlPx6G4lJJaz0g89LmjBaEjGUG8P W3Phh9db3hjxUIX5UC0jg5ai2XZ7u_wXn2Muk61N1eRCZ0oA2S25YDPK1dh. 3VQ6pH8SSBxVkQHUJXbZUNqLAzi5V5wRS7oeitXERGgA2DiZB268.rJxS7di OMT5eGoITG4LnAo1M3nsVQ6xceHDd4v6KD9KfBgTHX_iLUv_skCv4dVUgVvj edKOFiOMHBTpJ9J9BECjTTzEUpc.fCNUcRwSsiSkqbRhUsAdCbxQZir3Nb1Z 6FzI6J2eNqpj4azjmDeI15R8MyN7VFc6bl6pCZySk2Tx5SQESDm.sVkADSVR pI2nuscEjU3xo_qGUxbh5mbAA17K2zYpcFXaOce8_9Eszos5pURCcdtBYUqI I_DOtvNe.zWY1ShRcr9ZzTj3ibmc7NBmvumhVMjqirb12mfJ6oxHv8d86gze HtAJmJghczUg5otSzdxSgEJJxjMZrzSidJ9FP.gPiPWtuukz82YpZ32MnCVs 6.V2DRxpUmZa31KH93QSEzwMlCn3FFTLBv9izcjoFP81yeAn.3QloF8XIC3K WmtXtloyeGjuygAhlkd_prXmMGGC5JmPlY8xu4k1NavkdDh6pG6zIkt83Wsd p.D.0BgM \nX-Originating-IP: [75.30.245.45] \nAuthentication-Results: mta1287.mail.ne1.yahoo.com from=yahoo-inc.com; domainkeys=neutral (no sig); from=yahoo-inc.com; dkim=pass (ok)" 
print(p.findall(test_str)) 

UPDATE

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

txt = "YOUR_STRING_HERE" 
values = []     # Resulting value list 
start_matching = False   # Bool flag to start matching the key-value pairs 
val = ""      # Temp string to keep multiline values 
for line in txt.split("\n"): # Split the input into lines 
    if re.match(r"[^\s:]+:\s", line.strip()): # Check if the entry is found 
     start_matching = True # Start matching 
     if val:     # If a val is initialized, 
      values.append(val) # we save it to our list 
      val = ""   # Reset the temp string value 
     val += re.sub(r"^[^\s:]+:\s", "", line.strip()) # Append the value string start 
    else: 
     if start_matching:  # If matching has started, 
      val += "{}\n".format(line.strip()) # add the line to the value found 
print(values) 

См IDEONE demo

0

Python предоставляет пакет электронной почты, который может выполнять эти задачи низкого уровня для вас, но если вы хотите, чтобы узнать заголовок письма жесткий Кстати, ссылка является RFC5322 (formely RFC822)

Среди другой разумной информации вы найдете определение полого заголовка:

поле заголовка л начинающиеся с имени поля, за которым следует двоеточие (":"), за которым следует тело тела и завершается CRLF. A ДОЛЖНО быть составлено из печатных символов US-ASCII (то есть, символов, которые имеют значения от 33 до 126 включительно), за исключением двоеточия. Тело поля может состоять из печатных символов US-ASCII , а также пространства (SP, значение ASCII 32) и горизонтальной вкладки (HTAB, ASCII-значение 9) символов (вместе называемых пробелами символов, WSP). Тело поля не должно включать в себя CR и LF, за исключением при использовании в «складывании» и «раскрытие»

Складной позже определяются по формуле:

часть тела поля поля заголовка может быть разделена в многоканальное представление ; это называется «складыванием». Общее правило заключается в том, что везде, где эта спецификация допускает складывание белого пространства (а не только символов WSP), CRLF может быть вставлен перед любым WSP.

Это означает, что:

  • , когда линия не начинается с ПБВ (\s в регулярном выражении) начала строки до столбца является именем заголовка.
  • Когда линия начинается с WSP, это линия продолжения.

Так что регулярное выражение должно быть достаточно: '([\x21-\x7e]+?):'

Смежные вопросы