Разбор Python — несколько электронных писем в одном текстовом файле

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

Однако регулярное выражение o меня смутило. Текстовый файл, который я читаю, представляет собой комбинацию 9 сообщений электронной почты, сохраненных в один текстовый файл и открытых в Python в виде строки. Исходный отправитель (regex o) встречается в начале каждого нового сообщения в файле (9 раз)

Я хочу написать одного и того же исходного отправителя после каждого найденного CUSIP и NAME до тех пор, пока не будет сопоставлен другой исходный отправитель.

Я использую xlwt3 и wincom32.

Пример из текстового файла с комбинированными электронными письмами, что очень стандартно:

--- Original Sender: TOM MADEUPNAME, SOME BANK, N. ---
----- Original Message -----
From: TOM MADEUPNAME (SOME BANK, N.)
To: BOB THISISMYEMAIL (XYZ INVESTMENTS, INC)
At:  8/31  8:53:25
**Offerings**

Mezz ReRemics
Cusip      Description       Original Current Cashflow Collat Offering
05531UAB6  BCAP 2009-RR5 1A2   18,745  18,745 Snr Sup  Fxd      45.000

Prime/Alt-A Fixed
Cusip      Description       Original Current Cashflow Collat Offering
059487AE8  BOAA 2006-6 CB5     25,940  14,350 Seq      Fxd      83.000
12544XAX3  CWHL 2007-9 A13     10,190  10,190 Ssnr Nas Fxd      92.500
17312XAJ3  CMSI 2007-4 1A9      2,871   2,741 Spr Snr  Fxd      86.000

--- Original Sender: JOE MADEUPNAME, EUROPEAN BANK SECURI ---
----- Original Message -----
From: JOE MADEUPNAME (EUROPEAN BANK SECURI)
To: BOB THISISMYEMAIL (XYZ INVESTMENTS, INC)
At:  8/31  8:20:16

8-31-2011 

Alt-A Fixed
Bond            O/F    C/F    Cpn  FICO CAL WALB  60+    Notes             Offer
CSMC 06-9 7A1   25.00  11.97  L+45  728  26  578  35.21  FLT,AS,0.0%       50-00
LXS 07-10H 2A1  68.26  34.01  L+16  744   6  125  33.98  SS,9.57%          42-00
CSMC 06-7 9A1   15.00   7.81  L+30  688   5  198  46.46  SS,0.0%           29-16

Prime Hybrid 
Bond            O/F     C/F   Cpn  FICO CAL WALB  60+    Notes             Offer
SARM 05-18 6A1  14.56   6.01  2.58  730  46  432  15.87  SEA,SS,5/1,12.3%  78-00

Alt-A Hybrid
Bond            O/F    C/F    Cpn  FICO CAL WALB  60+    Notes             Offer
ARMT 05-12 2A1  23.78  10.71  3.07  712  48  556  35.32  SS,5/1,4.9%       *SOLD

Option Arm
Bond                O/F    C/F   Cpn  FICO CAL WALB  60+    Notes          Offer
DBALT 07-OA4 1A1B  10.00   7.25  L+13  716  63  562  47.17  SS,OC,42.2%    64-16
--------------------------------------------------------------------------------------

Обновлено - работает

count_cusip = 0
count_name = 0
count_sender = 0 
cur_sender = ''
for line in lines:

    o = re.search(r"Original Sender:\s\b\w+\s\w+", line)
    if o:
        count_sender += 1
        ws.write(count_sender,2,o.group(0))
        ws.write(count_sender,2,cur_sender)
        cur_sender = o.group(0)

    m = re.search('[0-9]{3}[a-zA-Z0-9]{6}', line)
    if m:
        count_cusip += 1
        ws.write(count_cusip,0,m.group(0))
        ws.write(count_cusip,2,cur_sender)

    n = re.search('[A-Z]{3,5}\s[0-9]{1,4}\D{1,3}\S{1,3}\s{1,2}\w+', line)
    if n:
        count_name += 1
        ws.write(count_name,1,n.group(0))
        ws.write(count_cusip,2,cur_sender)

        o = re.search(r"Original Sender:\s\b\w+\s\w+", line)
        if o:
            cur_sender = o.group(0)

        ws.write(count_name,2,cur_sender)

Обновленный вывод - по желанию.

CUSIP   Bond Name           Original Sender
00442PAD2   ACE 2006-OP1 A2B        Original Sender: Nick Madeupname
12557YAE7   ARMT 05-12 2A1          Original Sender: Bobby Madeupname
39153VAT1   CSMC 06-9 7A1           Original Sender: Bobby Madeupname
05377RAE4   LXS 07-10H 2A1          Original Sender: Jane Madeupname
02005HAF0   CSMC 06-7 9A1           Original Sender: Jane Madeupname

person Captain Cretaceous    schedule 31.08.2011    source источник
comment
что такое ws.write()? Вы пишете в электронную таблицу, используя xlwt или как?   -  person steveha    schedule 01.09.2011
comment
было бы очень полезно, если бы вы могли опубликовать пример ввода, который вы пытаетесь обработать. Вы должны изменить имена, темы и содержание электронных писем, чтобы сохранить конфиденциальность, но оставить нетронутым общий формат, чтобы мы могли видеть, что вы пытаетесь проанализировать.   -  person steveha    schedule 01.09.2011
comment
Какова цель \b в вашем последнем регулярном выражении? Мне кажется, вы ищете ровно один пробел после двоеточия, после которого должен появиться хотя бы один буквенно-цифровой символ. Я бы подумал, что это по определению граница слов.   -  person John Y    schedule 01.09.2011


Ответы (2)


Ваш вопрос не совсем ясен, поскольку вы не показали образец вывода, но вот обоснованное предположение:

count_cusip = 0
count_name = 0
count_sender = 0 
cur_sender = ''
for line in lines:

    m = re.search('[0-9]{3}[a-zA-Z0-9]{6}', line)
    if m:
        count_cusip += 1
        ws.write(count_cusip,0,m.group(0))
        ws.write(count_cusip,2,cur_sender)

    n = re.search('[A-Z]{3,5}\s[0-9]{1,4}\D{1,3}\S{1,3}\s{1,2}\w+', line)
    if n:
        count_name += 1
        ws.write(count_name,1,n.group(0))
        ws.write(count_name,2,cur_sender)

    o = re.search(r"Original Sender:\s\b\w+\s\w+", line)
    if o:
        count_sender += 1
        cur_sender = o.group(0)

Вместо того, чтобы записывать исходного отправителя при обнаружении, вам нужно сохранить его и записать текущее значение для каждого cusip и имени.

person Jim Garrison    schedule 01.09.2011
comment
Я разместил вывод, чтобы помочь. Кажется, этот код вызывает ошибку перезаписи. Трассировка (последний последний вызов): ws.write(count_sender,5,cur_sender) Файл C:\Python31\lib\site-packages\xlwt3\worksheet.py, строка 961, запись self.row(r).write( c, label, style) Файл C:\Python31\lib\site-packages\xlwt3\row.py, строка 226, запись StrCell(self.__idx, col, style_index, self.__parent_wb.add_str(label)) Файл C :\Python31\lib\site-packages\xlwt3\row.py, строка 145, в insert_cell поднять исключение (msg) Исключение: попытка перезаписать ячейку: имя_листа='Список облигаций' rowx=1 colx=5 - person Captain Cretaceous; 01.09.2011
comment
Не зная, что делает ws.write и контекст, в котором вы работаете, невозможно понять, что вам нужно делать. Вывод, который вы показываете, явно не отражает того, что делает ws.write. - person Jim Garrison; 01.09.2011
comment
ws.write исходит из xlwt и записывает в ячейки в excel. Формат ws.write (строка, столбец, соответствие регулярному выражению). Цикл for читает текстовый файл построчно, и первый проход для регулярного выражения m соответствует cusip в строке и пишет, что через ws.write(1,0,'929766LY7') для excel, а регулярное выражение n соответствует bond_name и ставится в excel через ws.write(1,1,'WBMCMT 2003-C8 A4'). Я помогаю? - person Captain Cretaceous; 01.09.2011
comment
@dadashek: Хорошо, я обновил код, чтобы указать текущего исходного отправителя в столбце 3 каждой строки. Ваш пример по-прежнему не имеет смысла: почему исходный отправитель пуст, начиная с FAIRF? - person Jim Garrison; 01.09.2011

При любой возможности вы можете изменить формат на формат, распознаваемый модулем mailbox в стандартной библиотеке. Затем вы можете позволить этому модулю обрабатывать весь синтаксический анализ.

person Ross Patterson    schedule 01.09.2011