Разделить по элементам строки и создать словарь с {элементом, используемым для разделения: этот фрагмент текста}

Рассмотрим следующий текст:

"Mr. McCONNELL. yadda yadda jon stewart is mean to me. The PRESIDING OFFICER. Suck it up. Mr. McCONNELL. but noooo. Mr. REID. Really dude?" 

И список слов, чтобы разделить на:

["McCONNELL", "PRESIDING OFFICER", "REID"]

Я хочу, чтобы на выходе был словарь

{"McCONNELL": "yadda yadd jon stewart is mean to me. but noooo.", 
"PRESIDING OFFICER": "Suck it up. "
"REID": "Really dude?"}

Поэтому мне нужен способ разделения по элементам списка (по любому из этих имен), а затем знать, на какой из них он разделен, и иметь возможность сопоставить его с фрагментом текста в этом разделении. В случае, когда более одного фрагмента текста имеют один и тот же динамик (в данном примере "McCONNELL"), просто объедините строки.

Редактировать: вот функция, которую я использовал. Это работает на примере, но не является устойчивым, когда я пробую это в гораздо большем масштабе (и не ясно, почему это портит)

def split_by_speaker(txt, seps):
    '''
    Given raw text and a list of separators (generally possible speaker names), splits based 
    on those names and returns a dictionary of text attributable to that name 
    '''
    speakers = []
    default_sep = seps[0]
    rv = {}

    for sep in seps:
        if sep in txt: 
            all_occurences = [m.start() for m in re.finditer(sep, txt)]
            for occ in all_occurences: 
                speakers.append((sep, occ))

            txt = txt.replace(sep, default_sep)
    temp_t = [i.strip() for i in txt.split(default_sep)][1:]
    speakers.sort(key = lambda x: x[1])
    for i in range(len(temp_t)): 
        if speakers[i][0] in rv: 
            rv[speakers[i][0]] = rv[speakers[i][0]] + " " + temp_t[i]
        else: 
            rv[speakers[i][0]] = temp_t[i]
    return rv 

1 ответ

Решение

Используйте модуль re из стандартной библиотеки для определения разбиений. Подсказка: разделитель "разделитель" - регулярное выражение - может иметь вид: (WORD1|WORD2|WORD3)

Посмотрите эти примеры, каковы результаты re.split.

import re

text = "Mr. McCONNELL. yadda yadda jon stewart is mean to me. The PRESIDING OFFICER. Suck it up. Mr. McCONNELL. but noooo. Mr. REID. Really dude?"

speakers = ["McCONNELL", "PRESIDING OFFICER", "REID"]

speakers_re = re.compile('(' + '|'.join([re.escape(s) for s in speakers]) + ')')

print speakers_re.split(text)

Результат:

['Mr. ', 'McCONNELL', 
 '. yadda yadda jon stewart is mean to me. The ', 
 'PRESIDING OFFICER', '. Suck it up. Mr. ', 
 'McCONNELL', '. but noooo. Mr. ', 'REID', '. Really dude?']

Удаление ненужных знаков препинания также можно выполнить с помощью регулярных выражений или простых методов.rstrip() и.lstrip() для строк.

Другие вопросы по тегам