olf*_*udi 1 python regex character-class python-3.x
我需要清理一些文本,如下面的代码所示:
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))
Run Code Online (Sandbox Code Playgroud)
并且这段代码必须给我一个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 }-=
Run Code Online (Sandbox Code Playgroud)
我正在使用 Python 3.6,特别是 Anaconda 构建 Anaconda3-2018.12-Windows-x86_64。
您的字符类(如回溯所示)无效;}谈到以后=的序号值(}125,=61),以及-它们之间意味着它试图以匹配任何字符}的顺序来=的,并在两者之间。由于字符范围必须从低序数到高序数,125->61 是无意义的,因此是错误的。
在某种程度上,你很幸运;如果 周围的字符-被颠倒了,例如=-},您会默默地删除从序号 61 到 125(含)的所有字符,这将包括所有标准的 ASCII 字母,以及一堆标点符号,包括小写和大写。
您可以通过删除-字符类中的第二个来解决此问题(您已经将它包含在不需要转义的类的开头),从
text = re.sub(r"[-()\"#/@;:<>{}-=~|.?,]", "", text)
Run Code Online (Sandbox Code Playgroud)
到
text = re.sub(r"[-()\"#/@;:<>{}=~|.?,]", "", text)
Run Code Online (Sandbox Code Playgroud)
但我建议在这里删除正则表达式;大量文字标点符号出错的风险很高,还有其他一些根本不涉及正则表达式的方法应该可以正常工作并且不会让你担心如果你逃避了所有重要的东西(另一种方法是过度逃避,这使得正则表达式不可读,并且仍然容易出错)。
相反,用简单的str.translatecall替换该行。首先,在函数之外,制作一个要删除的东西的翻译表:
# The redundant - is harmless here since the result is a dict which dedupes anyway
killpunctuation = str.maketrans('', '', r"-()\"#/@;:<>{}-=~|.?,")
Run Code Online (Sandbox Code Playgroud)
然后替换该行:
text = re.sub(r"[-()\"#/@;:<>{}-=~|.?,]","",text)
Run Code Online (Sandbox Code Playgroud)
和:
text = text.translate(killpunctuation)
Run Code Online (Sandbox Code Playgroud)
它的运行速度至少应该与正则表达式一样快(可能更快),而且不容易出错,因为没有字符具有特殊含义(翻译表只是从 Unicode 序数到 的映射None,意思是删除,另一个序数,意思是单个字符替换,或一个字符串,意思是 char -> multichar 替换;它们没有特殊转义的概念)。如果目标是删除所有 ASCII 标点符号,则最好使用string模块常量来定义转换表(这也使代码更具自文档性,因此人们不会想知道您是删除所有标点符号还是仅删除一些标点符号,以及是否有意):
import string
killpunctuation = str.maketrans('', '', string.punctuation)
Run Code Online (Sandbox Code Playgroud)
碰巧,您现有的字符串不会删除所有标点符号(它忽略,除其他事项外,^,!,$,等),所以这种变化可能是不正确的,但如果它是正确的,绝对做到这一点。如果它应该是标点符号的一个子集,你肯定想添加一个关于如何选择标点符号的评论,这样维护者就不会怀疑你是否犯了错误。
| 归档时间: |
|
| 查看次数: |
4790 次 |
| 最近记录: |