2012-02-04 3 views
1

здесь приведен пример текстового файла, я работаю с:навигационного поиск текстовых файлов в Python

<Opera> 

Tristan/NNP 
and/CC 
Isolde/NNP 
and/CC 
the/DT 
fatalistic/NN 
horns/VBZ 
The/DT 
passionate/JJ 
violins/NN 
And/CC 
ominous/JJ 
clarinet/NN 
;/: 

Прописных буквами после косых черт являются странными тегами. Я хочу, чтобы иметь возможность искать файл для чего-то вроде "NNP,CC,NNP" и вернуть программу для этого сегмента "Tristan and Isolde", три слова в строке, которые соответствуют этим тэгам в строке.

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

+0

Насколько большой файл? (Из более ранней записи один из ваших файлов был слишком велик, чтобы хранить несколько копий в памяти.) Есть ли возврат каретки или все это одна большая горизонтальная линия? – DSM

ответ

0

похоже, что текст был, возможно, подготовлен Natural Language Toolkit (nltk).

Использование NLTK, вы можете разметить текст, разделить маркер в (слово, part_of_speech) кортежей, и перебирать ngrams, чтобы найти те, которые соответствуют шаблону:

import nltk 
pattern = 'NNP,CC,NNP' 
pattern = [pat.strip() for pat in pattern.split(',')] 
text = '''Tristan/NNP and/CC Isolde/NNP and/CC the/DT fatalistic/NN horns/VBZ 
      The/DT passionate/JJ violins/NN And/CC ominous/JJ clarinet/NN ;/:''' 
tagged_token = [nltk.tag.str2tuple(word) for word in nltk.word_tokenize(text)] 
for ngram in nltk.ingrams(tagged_token,len(pattern)): 
    if all(gram[1] == pat for gram,pat in zip(ngram,pattern)): 
     print(' '.join(word for word, pos in ngram))  

дающий

Tristan and Isolde 

Связанные ссылка:

1
>>> import re 
>>> s = "Tristan/NNP and/CC Isolde/NNP and/CC the/DT fatalistic/NN horns/VBZ The/DT passionate/JJ violins/NN And/CC ominous/JJ clarinet/NN ;/:" 
>>> re.findall("(\w+)/NNP (\w+)/CC (\w+)/NNP", s) 
[('Tristan', 'and', 'Isolde')] 

Аналогичным образом, вы можете делать то, что вам нужно.

EDIT: более обобщенный.

>>> import re 
>>> pattern = 'NNP,CC,NNP' 
>>> pattern = pattern.split(",") 
>>> p = "" 
>>> for i in pattern: 
...  p = p + r"(\w+)/"+i+ r"\n" 
>>> f = open("yourfile", "r") 
>>> s = f.read() 
>>> f.close() 
>>> found = re.findall(p, s, re.MULTILINE) 
>>> found #Saved in found 
[('Tristan', 'and', 'Isolde')] 
>>> found_str = " ".join(found[0]) #Converted to string 
>>> f = open("written.txt", "w") 
>>> f.write(found_str) 
>>> f.close() 
+0

Спасибо за помощь. У меня есть несколько вопросов об этом методе. Могу ли я вызвать текстовый файл вместо s? Кроме того, где re.findall возвращает все, что он нашел? Может ли это быть выписано и в текстовый файл. Еще раз спасибо, это трудно изучить этот материал по своему усмотрению. –

+0

@EnglishGrad Проверьте обновленный ответ. –

+0

Спасибо, ваш ответ определенно помог. Я читаю регулярные выражения, но это довольно сложно. Мне нужно найти еще один тег для каждого матча. Мне нужно найти все, что внутри, и тег xml. Поэтому, когда я нахожу совпадение, я хочу посмотреть вперед, пока не найду тег и не распечатаю все, что находится внутри скобок. Могу ли я сделать это с помощью RE? –

1

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

text = ("Tristan/NNP and/CC Isolde/NNP and/CC the/DT fatalistic/NN horns/VBZ " 
    "The/DT passionate/JJ violins/NN And/CC ominous/JJ clarinet/NN") 

tags = ["NNP", "CC", "NNP"] 
tags_pattern = r"\b" + r"\s+".join(r"(\w+)/{0}".format(tag) for tag in tags) + r"\b" 
# gives you r"\b(\w+)/NNP\s+(\w+)/CC\s+(\w+)/NNP\b" 

from re import findall 
print(findall(tags_pattern, text)) 
+0

Wutz, Это отлично работало. Я использовал ваш код для доступа к текстовому файлу. Есть ли способ объяснить мне RE? В моем файле есть теги, подобные XML, и каждый раз, когда я нахожу совпадение с указанным выше кодом, я хочу вернуться к началу файла, пока не найду этот тег XML и не поставлю его с совпадением. Есть ли способ сделать это с помощью кода выше?Еще раз спасибо за помощь в этом, я никогда раньше не использовал RE. –