Раскрашивание текста в терминале по частям речи

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

До сих пор я пытался использовать для этой цели модули nltk и colorama.

import nltk
from colorama import Fore

Этот код найдет существительные и глаголы, так что глаголы будут VB или VBD, а существительные NN.

s = nltk.word_tokenize(sample_sentence)
tagged_text = nltk.pos_tag(s)
print tagged_text

[('Stately', 'RB'), (',', ','), ('plump', 'VB'), ('Buck', 'NNP'), ('Mulligan', 'NNP'), ('came', 'VBD'), ('from', 'IN'), ('the', 'DT'), ('stairhead', 'NN'), (',', ','), ('bearing', 'VBG'), ('a', 'DT'), ('bowl', 'NN'), ('of', 'IN'), ('lather', 'NN'), ('on', 'IN'), ('which', 'WDT'), ('a', 'DT'), ('mirror', 'NN'), ('and', 'CC'), ('a', 'DT'), ('razor', 'NN'), ('lay', 'NN'), ('crossed', 'VBD'), ('.', '.')]

Когда я хочу напечатать цветной текст, я буду использовать:

print Fore.BLUE + some_noun
print Fore.GREEN + some_verb
print Fore.BLACK + something_else

У меня проблема с печатью предложения. Как бы вы перебрали tagged_text, чтобы он печатал sample_sentence без изменений (будут применены только нужные цвета)?


person xralf    schedule 29.10.2012    source источник


Ответы (1)


Как насчет этого? Он сохраняет пробелы точно так же, как в исходном тексте. Хотя я считаю, что глаголы должны быть красными.

from colorama import Fore, init
import re
init()

tagged_text = [('Stately', 'RB'), (',', ','), ('plump', 'VB'), ('Buck', 'NNP'), ('Mulligan', 'NNP'), ('came', 'VBD'),
                ('from', 'IN'), ('the', 'DT'), ('stairhead', 'NN'), (',', ','), ('bearing', 'VBG'), ('a', 'DT'), 
                ('bowl', 'NN'), ('of', 'IN'), ('lather', 'NN'), ('on', 'IN'), ('which', 'WDT'), ('a', 'DT'),
                ('mirror', 'NN'), ('and', 'CC'), ('a', 'DT'),('razor', 'NN'), ('lay', 'NN'), ('crossed', 'VBD'),
                ('.', '.'), ('The', 'DET'), ('function', 'NN'), ('f', 'SYM'), ('(','('),('x','SYM'),(',',','),
                ('y','SYM'),(')',')'),('takes','VB'), ('two', 'CD'), ('arguments', 'NN'), ('.','.')]
origtext = 'Stately, plump Buck Mulligan came from the stairhead, bearing a bowl of lather on which a mirror and a razor lay crossed. The function f(x,y) takes two arguments.'

colordict = {'VB': Fore.GREEN, 'VBD': Fore.GREEN, 'NN': Fore.BLUE}

colorwords = ''
for word, tag in tagged_text:
    color = Fore.BLACK
    word = re.match(r'\s*%s\s*' % re.escape(word), origtext).group()
    origtext = origtext.split(word,1)[1]
    if tag in colordict:
        color = colordict[tag]
    colorwords += color + word

print colorwords
person Junuxx    schedule 29.10.2012
comment
Здесь каждое слово с новой строки. Предложение должно быть напечатано как оригинальное предложение, только окрашено. - person xralf; 29.10.2012
comment
@xralf Если вы добавите запятую после оператора печати, он будет напечатан в той же строке. print "Cow say MOO!!", - person CoffeeRain; 29.10.2012
comment
@CoffeeRain Я знаю, но предложение будет другим (перед знаками препинания будет больше нежелательных пробелов) - person xralf; 29.10.2012
comment
@Junuxx Это не так просто. Предложение может быть похоже на The function f(a, b) takes two arguments. - person xralf; 29.10.2012
comment
@xralf: Это не совсем пухлый Бак Маллиган, не так ли? Вы должны привести лучший пример, потому что не очевидно, как `f (a, b) будет размечено. Тем не менее, одна или две замены регулярных выражений должны легко это исправить. - person Junuxx; 29.10.2012
comment
@Junuxx Пробел в исходном предложении (sampleSentence) не должен меняться, но вы правы - предложение также неправильно токенизировано, поэтому будут применены неправильные цвета, но я также хотел бы сохранить пробел. Обратите внимание, что первое предложение также неправильно токенизировано (например, слово lay). - person xralf; 29.10.2012
comment
@xralf: Нет, токенизация lay в порядке, хотя она помечена неправильно. См. решение проблемы с пробелами в (снова) обновленном коде. Цветовые символы Colorama применяются к совпадающим словам и окружающим их пробелам из исходного текста. - person Junuxx; 29.10.2012
comment
Хорошо, я принял ответ. кстати. Я заметил, что теггер POS довольно ненадежен, поэтому моя идея и фрагмент в конце концов бесполезны. - person xralf; 30.10.2012
comment
@xralf: Это потому, что вы используете ярлык nltk.pos_tag, в котором используется мусорный корпус (Wall Street Journal - совершенно нерепрезентативный английский). Прочтите разделы 5.4–5.6 этого и попробуйте лучший корпус. . Удачи! - person Junuxx; 30.10.2012