使用 python 清理文本并重新

Cleaning Text with python and re

我需要像下面的代码一样清理一些文本:

import re
def clean_text(text):
    text = text.lower()
    #foction de replacement
    text = re.sub(r"i'm","i am",text)
    text = re.sub(r"she's","she is",text)
    text = re.sub(r"can't","cannot",text)
    text = re.sub(r"[-()\"#/@;:<>{}-=~|.?,]","",text)
    return text

clean_questions= []
for question in questions: 
    clean_questions.append(clean_text(question))

并且此代码必须给我 questions 列表干净但我得到干净的 questions 空。我重新打开 spyder 并且列表已满但没有被清理然后重新打开它并且我得到它是空的.. 控制台错误说:

In [10] :clean_questions= [] 
   ...: for question in questions: 
   ...: clean_questions.append(clean_text(question))
Traceback (most recent call last):

  File "<ipython-input-6-d1c7ac95a43f>", line 3, in <module>
    clean_questions.append(clean_text(question))

  File "<ipython-input-5-8f5da8f003ac>", line 16, in clean_text
    text = re.sub(r"[-()\"#/@;:<>{}-=~|.?,]","",text)

  File "C:\Users\hp\Anaconda3\lib\re.py", line 192, in sub
    return _compile(pattern, flags).sub(repl, string, count)

  File "C:\Users\hp\Anaconda3\lib\re.py", line 286, in _compile
   p = sre_compile.compile(pattern, flags)

  File "C:\Users\hp\Anaconda3\lib\sre_compile.py", line 764, in compile
    p = sre_parse.parse(p, flags)

  File "C:\Users\hp\Anaconda3\lib\sre_parse.py", line 930, in parse
    p = _parse_sub(source, pattern, flags & SRE_FLAG_VERBOSE, 0)

  File "C:\Users\hp\Anaconda3\lib\sre_parse.py", line 426, in _parse_sub
    not nested and not items))

  File "C:\Users\hp\Anaconda3\lib\sre_parse.py", line 580, in _parse
    raise source.error(msg, len(this) + 1 + len(that))

error: bad character range }-=

我正在使用 Python 3.6,特别是 Anaconda build Anaconda3-2018。12-Windows-x86_64。

您需要将特殊字符正确转义并括在方括号中

re.sub(r'[-\(\)\"#\/@;:<>\{\}\-=~|\.\?]', '', some_text)

用于特殊字符(即不是字母或数字)的更通用的正则表达式是

[^a-zA-Z0-9]

您的字符class(如回溯所示)无效; } 在序数值 = 之后(} 是 125,= 是 61),它们之间的 - 表示它试图匹配任何字符从 } 的序数到 = 之间。由于字符范围必须从低序数到高序数,125->61 是无意义的,因此是错误。

在某种程度上你很幸运;如果 - 周围的字符被颠倒了,例如=-},你会悄悄地删除从序数 61 到 125(含)的所有字符,这将包括所有标准的 ASCII 字母,包括一堆标点符号,包括小写和大写。

你可以通过删除你的角色 class 中的第二个 - 来解决这个问题(你已经将它包含在 class 的开头,它不需要转义),从

text = re.sub(r"[-()\"#/@;:<>{}-=~|.?,]", "", text)

text = re.sub(r"[-()\"#/@;:<>{}=~|.?,]", "", text)

但我建议在这里删除正则表达式;大量文字标点符号出错的风险很高,还有其他完全不涉及正则表达式的方法应该可以正常工作,如果您转义了所有重要的东西,也不会让您担心(另一种方法是过度转义,这使得正则表达式不可读,并且仍然容易出错)。

而是将该行替换为 a simple str.translate call. First off, outside the function, make a translation table of the things to remove:

# The redundant - is harmless here since the result is a dict which dedupes anyway
killpunctuation = str.maketrans('', '', r"-()\"#/@;:<>{}-=~|.?,")

然后替换行:

text = re.sub(r"[-()\"#/@;:<>{}-=~|.?,]","",text)

与:

text = text.translate(killpunctuation)

它应该 运行 至少和正则表达式一样快(可能更快),而且它更不容易出错,因为没有字符有特殊含义(翻译 table 只是从Unicode 序数到 None,意思是删除,另一个序数,意思是单个字符替换,或者一个字符串,意思是字符 -> 多字符替换;它们没有特殊转义的概念)。如果目标是消除所有 ASCII 标点符号,您最好使用 string 模块常量来定义翻译 table(这也使代码更加自文档化,所以人们不会怀疑如果您要删除所有标点符号或仅删除一些标点符号,以及是否是故意的):

import string
killpunctuation = str.maketrans('', '', string.punctuation)

碰巧,您现有的字符串并未删除所有标点符号(它遗漏了 ^!$ 等),因此此更改可能不正确,但如果正确,一定要做到。如果它应该是标点符号的一个子集,您肯定想添加关于该标点符号是如何选择的评论,这样维护者就不会怀疑您是否犯了错误。

使用这个对我有用

def clean_text(text):
    text = text.lower()
    text = re.sub('\[.*?\]', '', text)
    text = re.sub('https?://\S+|www\.\S+', '', text)
    text = re.sub('<.*?>+', '', text)
    text = re.sub('[%s]' % re.escape(string.punctuation), '', text)
    text = re.sub('\n', '', text)
    text = re.sub('\w*\d\w*', '', text)
    return text