REPLACE_BY_SPACE_RE = re.compile('[/(){}\[\]\|@,;]')
BAD_SYMBOLS_RE = re.compile('[^0-9a-z #+_]')
STOPWORDS = set(stopwords.words('english'))
def clean_text(text):
"""
text: a string
return: modified initial string
"""
text = text.lower() # lowercase text
text = REPLACE_BY_SPACE_RE.sub(' ', text) # replace REPLACE_BY_SPACE_RE symbols by space in text. substitute the matched string in REPLACE_BY_SPACE_RE with space.
text = BAD_SYMBOLS_RE.sub('', text) # remove symbols which are in BAD_SYMBOLS_RE from text. substitute the matched string in BAD_SYMBOLS_RE with nothing.
text = text.replace('x', '')
text = ' '.join(word for word in text.split() if word not in STOPWORDS) # remove stopwords from text
return text
OP
然后我测试了这段代码,以了解语法及其用途
BAD_SYMBOLS_RE = re.compile('[^0-9a-z #+_]') text = '[0a;m]' BAD_SYMBOLS_RE.sub(' ', text) # returns ' 0a m ' whilst I thought it would return ' ; '
问题:尽管在
0
中指定了a
,但是为什么代码没有替换m
,0-9a-z
和[ ]
?为什么未指定该字符却替换了;
?编辑,以避免被标记为重复项
我对代码的看法是:
- 行
BAD_SYMBOLS_RE = re.compile('[^0-9a-z #+_]')
令人困惑。在#
中包含字符+
,_
和[ ]
使我认为试图删除列表中字符的行(因为英语词典中没有单词会包含那些bad字符
#+_
,我相信吗?)。因此,它使我将^
解释为字符串的开头(而不是取反)。因此,原来的帖子(由Tim Pietzcker和Raymond Hettinger友善回答)。- 我还认为代码
text = text.replace('x', '')
(原本是要删除原始数据中被掩盖为XXX-XXXX ....的ID)将导致不良结果,例如单词next
将成为net
。其他问题
:
- 我的看法合理吗?
- 您能否为文本预处理(英语(英语))分类推荐整体/通用代码?
[基本上,[abc]
表示“ a
,b
或c
中的任何一个”,而[^abc]
表示“任何
not a
,b
或[ C0]“。
c
,#
和+
以外的所有非数字,非字母字符,这说明了得到的结果。一般规则
方括号指定任何一个字符。大约_
是[xyz]
的捷径,但没有创建组。
同样,(x|y|z)
是[a-z]
的捷径。
字符集的解释可能有些棘手。起点和终点将转换为它们的(a|b|c|...|y|z)
,并从此处推断出匹配字符的范围。例如,ordinal positions将
A转换为65,将z转换为122,因此包括从65到122的所有内容。这意味着它还匹配诸如^之类的字符,该字符将转换为94。这还意味着诸如ö之类的字符将不匹配,因为它将转换为246范围之外的字符。
关于字符类的另一种有趣形式使用^
来反转选择。例如,[A-z]
表示“不在a到z范围内的任何字符。详细信息在[^a-z]
的“字符集”部分。特定问题
在OP的示例中为re docs,开始时的插入符号^反转范围,以使列出的符号从搜索中被排除
。这就是为什么代码did n't
替换0,a和m的原因,尽管在BAD_SYMBOLS_RE = re.compile('[^0-9a-z #+_]')
中指定了0-9a-z
。本质上,它将指定字符视为好字符。希望这会有所帮助:-)