使用 for 循环从标记化文本中删除标点符号

Remove punctuation marks from tokenized text using for loop

我正在尝试从 python 中的标记化文本中删除标点符号,如下所示:

word_tokens = ntlk.tokenize(text)
w = word_tokens
for e in word_tokens:
    if e in punctuation_marks:
        w.remove(e)

这有点管用,我设法删除了很多标点符号,但由于某些原因,word_tokens 中的很多标点符号仍然存在。 如果我再次 运行 代码,它会再次删除更多的标点符号。 运行 将相同的代码输入 3 次后,所有标记都将被删除。为什么会这样?

punctuation_marks 是列表、字符串还是字典似乎并不重要。我还尝试遍历 word_tokens.copy() ,它做得更好一些,它第一次几乎删除了所有标记,第二次也删除了所有标记。 有没有一种简单的方法可以解决此问题,以便仅 运行 代码一次就足够了?

您正在从迭代的同一个列表中删除元素。您似乎已经意识到潜在的问题,这就是您添加以下行的原因:

w = word_tokens

然而,该行实际上并没有创建 word_tokens 引用的对象的副本,它只是使 w 引用了同一个对象。为了创建副本,您可以使用切片运算符,将上面的行替换为:

w = word_tokens[:]

我建议您尝试使用正则表达式并将您的结果附加到新列表中,而不是直接操作 word_tokens 的结果:

word_tokens = ntlk.tokenize(text)
w_ = list()
for e in word_tokens:
    w_.append(re.sub('[.!?\-]', e))

您正在修改实际 word_tokens,这是错误的。

例如,假设您有类似 A?!B 的内容,其索引为:A:0, ?:1, !:2, B:3。你的 for 循环有一个计数器(比如 i),它在每个循环中增加。假设您删除了使数组索引向后移动的 ?(意味着 i=1)(新索引是:A:0, !:1, B:2)和您的计数器递增(i=2)。所以你在这里漏掉了 ! 字符!

最好不要弄乱原来的字符串,直接复制到一个新的。

为什么不添加不是标点符号的标记呢?

word_tokens = ntlk.tokenize(text)
w = list()
for e in word_tokens:
    if e not in punctuation_marks:
        w.append(e)

建议: 我看到你正在创建单词标记。如果是这种情况,我建议您在标记文本之前删除标点符号。您可以使用已经可用的翻译功能(在字符串库下)。

# Import the library
import string

# Initialize the translate to remove punctuations
tr = str.maketrans("", "", string.punctuation)

# Remove punctuations
text = text.translate(tr)

# Get the word tokens
word_tokens = ntlk.tokenize(text)

如果你想做句子标记化,那么你可以做如下的事情:

from nltk.tokenize import sent_tokenize

texts = sent_tokenize(text)
for i in range(0, len(texts))
    texts[i] = texts[i].translate(tr)