【问题标题】:remove only the unknown words from a text but leave punctuation and digits仅从文本中删除未知单词,但保留标点符号和数字
【发布时间】:2019-03-13 19:08:46
【问题描述】:

我有一段法语文本,其中包含用空格分隔的单词(例如 répu blique*)。我想从文本中删除这些分隔的单词并将它们附加到列表中,同时在文本中保留标点符号和数字。我的代码适用于附加分开的单词,但不能保留文本中的数字。

import nltk
from nltk.tokenize import word_tokenize

import re

with open ('french_text.txt') as tx: 
#opening text containing the separated words
    #stores the text with the separated words
    text = word_tokenize(tx.read().lower()) 


with open ('Fr-dictionary.txt') as fr:  #opens the dictionary
    dic = word_tokenize(fr.read().lower()) #stores the first dictionary

pat=re.compile(r'[.?\-",:]+|\d+')

out_file=open("newtext.txt","w") #defining name of output file
valid_words=[ ] #empty list to append the words checked by the dictionary 
invalid_words=[ ] #empty list to append the errors found

for word in text:
    reg=pat.findall(word)
    if reg is True:
        valid_words.append(word)
    elif word in dic:
        valid_words.append(word)#appending to a list the words checked 
    else:
        invalid_words.append(word) #appending the invalid_words



a=' '.join(valid_words) #converting list into a string

print(a) #print converted list
print(invalid_words) #print errors found

out_file.write(a) #writing the output to a file

out_file.close()

因此,使用此代码,我的错误列表带有数字。

['ments', 'prési', 'répu', 'blique', 'diri', 'geants', '»', 'grand-est', 'elysée', 'emmanuel', 'macron', 'sncf', 'pepy', 'montparnasse', '1er', '2017.', 'geoffroy', 'hasselt', 'afp', 's', 'empare', 'sncf', 'grand-est', '26', 'elysée', 'emmanuel', 'macron', 'sncf', 'saint-dié', 'epinal', '23', '2018', 'etat', 's', 'vosges', '2018']

我认为问题出在正则表达式上。有什么建议么?谢谢!!

【问题讨论】:

  • 更容易显示示例文本以及您的正则表达式对它的作用。这更好,因为没有人知道您的文件中有什么或您如何使用它。
  • 换句话说,'你的输入是什么,你想要的输出是什么?'

标签: python regex list punctuation


【解决方案1】:

问题在于您检查reg is True 的if 语句。您不应将is 运算符与True 一起使用来检查pat.findall(word) 的结果是否为正(即您有匹配的单词)。

您可以这样做:

for word in text:
    if pat.match(word):
        valid_words.append(word)
    elif word in dic:
        valid_words.append(word)#appending to a list the words checked 
    else:
        invalid_words.append(word) #appending the invalid_words

【讨论】:

    【解决方案2】:

    警告用户:这实际上是一个复杂的问题,因为这完全取决于我们对单词的定义:

    • l’Académie一个字,j’eus呢?
    • gallo-romanes 一个单词,还是c'est-à-dire
    • J.-C. 怎么样?
    • xiv(e)(带上标,如 14 世纪)?
    • 然后是QDNQQ1LOL?

    这里有一个直接解决方案,总结如下:

    1. 将文本分成“单词”和“非单词”(标点符号、空格)
    2. 根据字典验证“单词”
    # Adjust this to your locale
    WORD = re.compile(r'\w+')
    
    text = "foo bar, baz"
    
    while True:
        m = WORD.search(text)
        if not m:
            if text:
                print(f"punctuation: {text!r}")
            break
        start, end = m.span()
        punctuation = text[:start]
        word = text[start:end]
        text = text[end:]
        if punctuation:
            print(f"punctuation: {punctuation!r}")
        print(f"possible word: {word!r}")
    
    possible word: 'foo'
    punctuation: ' '
    possible word: 'bar'
    punctuation: ', '
    possible word: 'baz'
    

    我感觉您正在尝试处理故意拼错/打散的单词,例如如果有人试图绕过论坛黑名单规则或语音分析。

    那么,更好的方法是:

    1. 使用字典识别什么是“单词”或“非单词”
    2. 然后拆分文本

    如果原始文本是为了避开计算机但可供人类阅读,那么最好的选择是 ML/AI,很可能是神经网络,例如用于识别图像中对象的 RNN。

    【讨论】:

    • 我已经找到了您指出的所有案例的解决方案。谢谢!!
    猜你喜欢
    • 2019-07-31
    • 2014-06-20
    • 2023-01-31
    • 1970-01-01
    • 1970-01-01
    • 2013-06-30
    • 2022-01-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多