Распечатать все токены в файле, помеченные морфологическим тегом

Я хочу напечатать все токены, которые помечены морфологическим тегом в файле. Пока что я написал код, показанный ниже.

def index(filepath, string):

    import re
    pattern = re.compile(r'(\w+)+')
    StringList = []
    StringList.append(string)

    with open(filepath) as f:
        for lineno, line in enumerate(f, start=1):
            words = set(m.group(1) for m in pattern.finditer(line))
            matches = [keyword for keyword in StringList if keyword in words]
            if matches:
                result = "{:<15} {}".format(','.join(matches), lineno)
                print(result)

    StringList.clear()



index('deneme.txt', '+Noun')

Вывод такой: я могу найти существительное в токене и номер строки, но не могу напечатать ту часть, которую я хотел. Я хочу только часть слова, которая находится перед знаком +.

Noun            1
Noun            2
Noun            3
Noun            4
Noun            5
Noun            6
Noun            7

Строки в моем файле примерно такие:

Türkiye+Noun ,+Punc terörizm+Noun+Gen ve+Conj kitle+Noun imha+Noun silah+Noun+A3pl+P3sg+Gen küresel+Adj düzey+Noun+Loc oluş+Verb+Caus+PastPart+P3sg tehdit+Noun+Gen boyut+Noun+P3sg karşı+Adj+P3sg+Loc ,+Punc tüm+Det ülke+Noun+A3pl+Gen yay+Verb+Pass+Inf2+Gen önle+Verb+Pass+Inf2+P3sg hedef+Noun+A3pl+P3sg+Acc paylaş+Verb+PastPart+P3pl ,+Punc daha+Noun güven+Noun+With ve+Conj istikrar+Noun+With bir+Num dünya+Noun düzen+Noun+P3sg için+PostpPCGen birlik+Noun+Loc çaba+Noun göster+Verb+PastPart+P3pl bir+Num aşama+Noun+Dat gel+Verb+Pass+Inf2+P3sg+Acc samimi+Adj ol+Verb+ByDoingSo arzula+Verb+Prog2+Cop .+Punc 
Türkiye+Noun+Gen ekonomik+Adj ve+Conj insani+Adj potansiyel+Noun+P3sg ,+Punc güç+Noun+With savun+Verb+Inf2 kapasite+Noun+P3sg ,+Punc ulus+Noun+A3pl+InBetween çatış+Verb+Inf2+A3pl+Gen önle+Verb+Pass+Inf2+P3sg ve+Conj barış+Noun+P3sg inşa+Noun çaba+Noun+A3pl+P3sg+Dat aktif+Adj katılım+Noun+P3sg+Gen yanısıra+PostpPCGen ,+Punc fark+Noun+With kültür+Noun ve+Conj gelenek+Noun+A3pl+Dat ait+PostpPCDat seçkin+Adj özellik+Noun+A3pl+Acc birleş+Verb+Caus+PresPart bir+Num bünye+Noun+Dat sahip+Noun ol+Verb+Inf2+P3sg ,+Punc kendi+Pron+P3sg bölge+Noun+P3sg+Loc ve+Conj öte+Noun+P3sg+Loc önem+Noun+With rol+Noun oyna+Verb+Inf2+P3sg+Acc sağla+Verb+Fut değer+Noun+With özellik+Noun+A3pl+Cop .+Punc 
Türkiye+Noun ,+Punc bu+Det önem+Noun+With katkı+Noun+Acc yap+Verb+Able+Inf1 için+PostpPCGen yeterli+Adj donanım+Noun+P3sg haiz+Adj bir+Num ülke+Noun+Cop ve+Conj gelecek+Noun nesil+Noun+A3pl için+PostpPCGen daha+Noun i+Noun+Acc bir+Num dünya+Noun oluş+Verb+Caus+Inf1 amaç+Noun+P3sg+Ins ,+Punc dost+Noun+A3pl+P3pl ve+Conj müttefik+Adj+A3pl+P3sg+Ins yakın+Noun bir+Num biçim+Noun+Loc çalış+Verb+Inf2+Dat devam+Noun et+Verb+Fut+Cop .+Punc 
Ab+Noun ile+PostpPCNom gümrük+Noun Alan+Noun+P3sg+Loc+Rel kurumsal+Adj ilişki+Noun+A3pl 
club+Noun toplantı+Noun+A3pl+P3sg 
Türkiye+Noun -+Punc At+Noun gümrük+Noun işbirlik+Noun+P3sg komite+Noun+P3sg ,+Punc Ankara+Noun Anlaşma+Noun+P3sg+Gen 6+Num madde+Noun+P3sg uyar+Verb+When ortaklık+Noun rejim+Noun+P3sg+Gen uygula+Verb+Pass+Inf2+P3sg+Acc ve+Conj geliş+Verb+Inf2+P3sg+Acc sağla+Verb+Inf1 üzere+PostpPCNom ortaklık+Noun Konsey+Noun+P3sg+Gen 2+Num /+Punc 69+Num sayılı+Adj karar+Noun+P3sg ile+Conj teknik+Noun komite+Noun mahiyet+Noun+P3sg+Loc kur+Verb+Pass+Narr+Cop .+Punc 
club+Noun toplantı+Noun+A3pl+P3sg 
nispi+Adj 
nisbi+Adj 
görece+Adj+With 
izafi+Adj 
obur+Adj 

Я хочу получить пример токенов при написании тега. Например, когда я пишу +Adj, я хочу получить все токены, которые включают +Adj (nispi, izafi .... (пример)).

2 ответа

Решение

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

Обратите внимание, что каждая строка ввода содержит несколько "токенов", например terörizm+Noun+Gen, Как видите, он содержит:

  • первое слово - фактическое слово из текста,
  • количество символов классификации, каждому из которых предшествует + голец.

Так:

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

Хорошая привычка это лишать завершающие пустые символы (по крайней мере, \n).

Обратите внимание, что ваш код содержит StringListТаким образом, вам известно, что эта функция может искать одно или несколько слов классификации.

Я запрограммировал это немного по-другому:

  • Второй параметр (lookFor) представляет собой список слов, который преобразуется в набор (lookForSet).
  • Набор слов (результат разбиения токена минус первое слово) также преобразуется в набор.

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

Таким образом, весь скрипт может выглядеть так:

import re

def index(fileName, lookFor):
    lookForSet = set(lookFor)  # Set of classification symbols to look for
    pat1 = re.compile(r'\s+')  # Regex to split line into tokens
    pat2 = re.compile(r'\+')   # Regex to split a token into words
    with open(fileName) as f:
        for lineNo, line in enumerate(f, start=1):
            line = line.rstrip()
            tokens = pat1.split(line)
            for token in tokens:
                words = pat2.split(token)
                word1 = words.pop(0)  # Initial word
                wordSet = set(words)  # Classification words
                commonWords = lookForSet.intersection(wordSet)
                if commonWords:
                    print("{:3}: {:<15} {}".format(lineNo, word1, ', '.join(commonWords)))

index('lines.txt', ['Noun', 'Gen'])

Часть выходных данных для моих входных данных (немного сокращенная версия), как показано ниже:

1: Türkiye         Noun
1: terörizm        Noun, Gen
1: kitle           Noun
1: imha            Noun
2: Türkiye         Noun, Gen
2: potansiyel      Noun

Это содержит:

  • номер строки источника,
  • первое слово токена,
  • какие слова классификации из lookFor были найдены в этом токене.

Расщепление на \w+ удалил + часть от того, что вы ищете, поэтому я вместо этого разделить на промежутки между ними. Тогда это был просто случай борьбы for а также in в правильном порядке для понимания списка.

def index(filepath, string):
    StringList = [string]

    with open(filepath) as f:
        for lineno, line in enumerate(f, start=1):
            words = line.split(' ')
            matches = [word for keyword in StringList for word in words if keyword in word]
            if matches:
                result = "{:<15} {}".format(','.join(matches), lineno)
                print(result)


index('deneme.txt', '+Adj')

Что приводит к результату:

küresel+Adj,karşı+Adj+P3sg+Loc,samimi+Adj 1
ekonomik+Adj,insani+Adj,aktif+Adj,seçkin+Adj 2
yeterli+Adj,haiz+Adj,müttefik+Adj+A3pl+P3sg+Ins 3
kurumsal+Adj    4
sayılı+Adj      6
nispi+Adj       8
nisbi+Adj       9
görece+Adj+With 10
izafi+Adj       11
obur+Adj        12

Я убрал строку StringList.clear() как-то это дало ошибку, хотя.

Работает как с Python 2.7, так и с 3.6+, хотя расширенные символы Юникода в вашем тексте смещают выравнивание, используя 2.7.

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