如何在特定令牌之前和之后获取单词?

时间:2014-08-08 09:09:57

标签: python regex nlp text-processing trigram

我目前正致力于一个简单创建基本语料库数据库和标记文本的项目。但似乎我陷入了困境。假设我们有这些东西:

import os, re

texts = []

for i in os.listdir(somedir): # Somedir contains text files which contain very large plain texts.
    with open(i, 'r') as f:
        texts.append(f.read())

现在我想在令牌之前和之后找到这个词。

myToken = 'blue'
found = []
for i in texts:
    fnd = re.findall('[a-zA-Z0-9]+ %s [a-zA-Z0-9]+|\. %s [a-zA-Z0-9]+|[a-zA-Z0-9]+ %s\.' %(myToken, myToken, myToken), i, re.IGNORECASE|re.UNICODE)
    found.extend(fnd)

print myToken
for i in found:
    print '\t\t%s' %(i)

我认为有三种可能性:令牌可能会开始判断,令牌可能会结束句子或令牌可能出现在句子的某处,所以我使用了上面的正则规则。当我跑步时,我遇到了这些事情:

blue
    My blue car # What I exactly want.
    he blue jac # That's not what I want. That must be "the blue jacket."
    eir blue phone # Wrong! > their
    a blue ali # Wrong! > alien
    . Blue is # Okay.
    is blue. # Okay.
    ...

我也试过了\ b \ w \ b或\ b \ W \ b的东西,但不幸的是那些没有返回任何结果而不是返回错误的结果。我试过了:

'\b\w\b%s\b[a-zA-Z0-9]+|\.\b%s\b\w\b|\b\w\b%s\.'
'\b\W\b%s\b[a-zA-Z0-9]+|\.\b%s\b\W\b|\b\W\b%s\.'

我希望问题不会太模糊。

3 个答案:

答案 0 :(得分:1)

让我们说令牌是测试。

        (?=^test\s+.*|.*?\s+test\s+.*?|.*?\s+test$).*

你可以使用lookahead。它不会吃掉任何东西,同时也会验证。

http://regex101.com/r/wK1nZ1/2

答案 1 :(得分:1)

我认为你想要的是:

  1. (可选)单词和空格;
  2. (始终)'blue';
  3. (可选)空格和单词。
  4. 因此,一个合适的正则表达式将是:

    r'(?i)((?:\w+\s)?blue(?:\s\w+)?)'
    

    例如:

    >>> import re
    >>> text = """My blue car
    the blue jacket
    their blue phone
    a blue alien
    End sentence. Blue is
    is blue."""
    >>> re.findall(r'(?i)((?:\w+\s)?{0}(?:\s\w+)?)'.format('blue'), text)
    ['My blue car', 'the blue jacket', 'their blue phone', 'a blue alien', 'Blue is', 'is blue']
    

    请参阅演示和逐令牌解释here

答案 2 :(得分:1)

正则表达式有时可能很慢(如果没有正确实现),而且在某些情况下,接受的答案对我不起作用。

所以我选择了暴力解决方案(不是说它是最好的解决方案),其中关键字可以由几个单词组成:

@staticmethod
def find_neighbours(word, sentence):
    prepost_map = []

    if word not in sentence:
        return prepost_map

    split_sentence = sentence.split(word)
    for i in range(0, len(split_sentence) - 1):
        prefix = ""
        postfix = ""

        prefix_list = split_sentence[i].split()
        postfix_list = split_sentence[i + 1].split()

        if len(prefix_list) > 0:
            prefix = prefix_list[-1]

        if len(postfix_list) > 0:
            postfix = postfix_list[0]

        prepost_map.append([prefix, word, postfix])

    return prepost_map

关键字之前或之后的空字符串分别表示关键字是句子中的第一个或最后一个单词。