Skip to main content
 首页 » 编程设计

python之删除单引号同时保留撇号 Python, NLTK

2025年05月04日9softidea

我正在尝试创建诗歌语料库的频率列表。该代码读取 .txt 文件并使用数据创建一个 .csv。

我正在努力解决的部分是从文本中删除不相关的标点符号。我到目前为止的相关代码是:

import nltk 
 
raw = open('file_name.txt', 'r').read() 
output = open('output_filename.csv','w') 
txt = raw.lower() 
 
pattern = r'''(?x)([A_Z]\.)+|\w+(-\w+)*|\.\.\|[][.,;"'?():-_`]''' 
tokenized = nltk.regexp_tokenize(txt,pattern) 

这几乎完美地工作,因为它保留了诸如 chimney-sweeper 之类的词中的连字符,但它也将收缩缩减为两个单独的词,这不是我想要的。

例如,我的文本文件(试运行的是 William Blake 的纯真之歌)包含以下行:

'Pipe a song about a Lamb!'

我想成为什么样的人

Pipe | a | song | about | a | Lamb

我之前使用的代码保留了缩写,但也给我留下了单词的单引号:

for punct in string.punctuation: 
    txt = txt.replace(punct,' ') 
re.sub(r'\r+',' ',txt) 

所以我会得到

'Pipe | a | song | about | a | Lamb

我想在这两者之间找到一个中间立场,因为我需要在诸如 O'er 和连字符之类的词中保留撇号,但去掉其他一切。

我知道这个话题在这个论坛上似乎已经用尽了,但我花了过去四天的时间尝试提供的每个示例,但未能让它们像宣传的那样工作,所以与其撕破我的头发我想我会尝试发布一个问题。

编辑:

标准分词器无法处理我的文本的原因似乎是一些撇号在奇怪的地方右/左倾斜的结果。我使用一堆 .replace() 指令产生了我想要的结果:

txt = txt.replace("\n", " ") 
#formats the text so that the line break counts as a space 
txt = txt.replace("”", " ") 
#replaces stray quotation marks with a space 
txt = txt.replace("“", " ") 
#replaces stray quotation marks with a space 
txt = txt.replace(" ’", " ") 
#replaces a right leaning apostrophe with a space if it follows a space(which now includes line breaks) 
txt = txt.replace(" ‘", " ") 
#replaces a left leaning apostrophe with a space if it follows a space 

我不怀疑有一种方法可以将所有这些整合到一行代码中,但我真的很高兴这一切都有效!

请您参考如下方法:

您可以拆分空格,然后去除每个单词开头和结尾的标点符号,而不是替换标点符号:

>>> import string 
>>> phrase = "'This has punctuation, and it's hard to remove!'" 
>>> [word.strip(string.punctuation) for word in phrase.split(" ")] 
['This', 'has', 'punctuation', 'and', "it's", 'hard', 'to', 'remove'] 

这会保留单词中的撇号和连字符,同时删除单词开头或结尾的标点符号。


请注意,独立的标点符号将被替换为空字符串"":

>>> phrase = "This is - no doubt - punctuated" 
>>> [word.strip(string.punctuation) for word in phrase.split(" ")] 
['This', 'is', '', 'no', 'doubt', '', 'punctuated'] 

这很容易过滤掉,因为空字符串的计算结果为 False:

filtered = [f for f in txt if f and f.lower() not in stopwords] 
                            # ^ excludes empty string