python3写的清洗文本代码在python2用不了,会出现各种编码问题,经过痛苦的一晚上加班终于搞完了,记录一下。
python2
def clean_text(content):
"""去除话题词,链接,@用户,图标,emoji,标点符号,空白符"""
query = re.sub(u"#[^#]*?#|<sina.*?>|@[^ ]*", "", content).replace("\xe2\x80\x8b", "")
#去除http链接
try:
URL_REGEX = re.compile(
u'(?i)http[s]?://(?:[a-zA-Z]|[0-9]|[#$%*-;=?&@~.&+]|[!*,])+',
re.IGNORECASE)
query = re.sub(URL_REGEX, "", query)
except:
# sometimes lead to "catastrophic backtracking"
zh_puncts1 = u",;、。!?()《》【】"
URL_REGEX = re.compile(u'(?i)((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>' + zh_puncts1 + u']+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:\'".,<>?«»“”‘’' + zh_puncts1 + u']))',
re.IGNORECASE)
query = re.sub(URL_REGEX, "", query.decode('utf8'))
#去除图标 表情
query = re.sub(u"\[\S+?\]", "", query.decode('utf8'))
# 去除真,图标式emoji
emoji_pattern = re.compile("["
u"\U0001F600-\U0001F64F" # emoticons
u"\U0001F300-\U0001F5FF" # symbols & pictographs
u"\U0001F680-\U0001F6FF" # transport & map symbols
u"\U0001F1E0-\U0001F1FF" # flags (iOS)
u"\U00002702-\U000027B0"
u"\u2600-\u2B55" u"\U00010000-\U0010ffff"
"]+", flags=re.UNICODE)
query = emoji_pattern.sub('', query.decode('utf8'))
#去除标点符号
allpuncs = re.compile(u"[~,\_《。》、?;:‘’"“”【「】」·!@¥…()—\,\<\.\>\/\?\;\:\'\"\[\]\{\}\~\`\!\@\#\$\%\^\&\*\(\)\-\=\+]")
query = re.sub(allpuncs, "", query.decode('utf8'))
#去除空白符
query = re.sub(u"(\s)+", "", query)
return query
python3
点击查看代码
def clean_text(text, remove_url=True, email=True, weibo_at=True, stop_terms=("转发",),
emoji=True, weibo_topic=False, deduplicate_space=True,
norm_url=False, norm_html=False, to_url=False,
remove_puncts=False, remove_tags=True, t2s=False,
expression_len=(1,6), linesep2space=False):
'''
进行各种文本清洗操作,特殊格式,网址,email,html代码,等等
:param text: 输入文本
:param remove_url: (默认使用)是否去除网址
:param email: (默认使用)是否去除email
:param weibo_at: (默认使用)是否去除\@相关文本
:param stop_terms: 去除文本中的一些特定词语,默认参数为("转发",)
:param emoji: (默认使用)去除\[\]包围的文本,一般是表情符号
:param weibo_topic: (默认不使用)去除##包围的文本,一般是话题
:param deduplicate_space: (默认使用)合并文本中间的多个空格为一个
:param norm_url: (默认不使用)还原URL中的特殊字符为普通格式,如(%20转为空格)
:param norm_html: (默认不使用)还原HTML中的特殊字符为普通格式,如(\ 转为空格)
:param to_url: (默认不使用)将普通格式的字符转为还原URL中的特殊字符,用于请求,如(空格转为%20)
:param remove_puncts: (默认不使用)移除所有标点符号
:param remove_tags: (默认使用)移除所有html块
:param t2s: (默认不使用)繁体字转中文
:param expression_len: 假设表情的表情长度范围,不在范围内的文本认为不是表情,不加以清洗,如[加上特别番外荞麦花开时共五册]。设置为None则没有限制
:param linesep2space: (默认不使用)把换行符转换成空格
:return: 清洗后的文本
'''
# unicode不可见字符
# 未转义
text = re.sub(r"[\u200b-\u200d]", "", text)
# 已转义
text = re.sub(r"(\\u200b|\\u200c|\\u200d)", "", text)
# 反向的矛盾设置
if norm_url and to_url:
raise Exception("norm_url和to_url是矛盾的设置")
if norm_html:
text = html.unescape(text)
#if to_url:
# text = urllib.parse.quote(text)
# if remove_tags:
# text = w3lib.html.remove_tags(text)
if remove_url:
try:
sina_url = re.compile(r'<sina.*?>')
text = re.sub(sina_url, "", text)
URL_REGEX = re.compile(
r'(?i)http[s]?://(?:[a-zA-Z]|[0-9]|[#$%*-;=?&@~.&+]|[!*,])+',
re.IGNORECASE)
text = re.sub(URL_REGEX, "", text)
except:
# sometimes lead to "catastrophic backtracking"
zh_puncts1 = ",;、。!?()《》【】"
URL_REGEX = re.compile(
r'(?i)((?:https?://|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}/)(?:[^\s()<>' + zh_puncts1 + ']+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:\'".,<>?«»“”‘’' + zh_puncts1 + ']))',
re.IGNORECASE)
text = re.sub(URL_REGEX, "", text)
if norm_url:
text = urllib.parse.unquote(text)
if email:
EMAIL_REGEX = re.compile(r"[-a-z0-9_.]+@(?:[-a-z0-9]+\.)+[a-z]{2,6}", re.IGNORECASE)
text = re.sub(EMAIL_REGEX, "", text)
if weibo_at:
text = re.sub(r"(回复)?(//)?\s*@\S*?\s*(:|:| |$)", " ", text) # 去除正文中的@和回复/转发中的用户名
if emoji:
# 去除括号包围的表情符号
# ? lazy match避免把两个表情中间的部分去除掉
if type(expression_len) in {tuple, list} and len(expression_len) == 2:
# 设置长度范围避免误伤人用的中括号内容,如[加上特别番外荞麦花开时共五册]
lb, rb = expression_len
text = re.sub(r"\[\S{"+str(lb)+r","+str(rb)+r"}?\]", "", text)
else:
text = re.sub(r"\[\S+?\]", "", text)
# text = re.sub(r"\[\S+\]", "", text)
# 去除真,图标式emoji
emoji_pattern = re.compile("["
u"\U0001F600-\U0001F64F" # emoticons
u"\U0001F300-\U0001F5FF" # symbols & pictographs
u"\U0001F680-\U0001F6FF" # transport & map symbols
u"\U0001F1E0-\U0001F1FF" # flags (iOS)
u"\U00002702-\U000027B0"
u"\u2600-\u2B55" u"\U00010000-\U0010ffff"
"]+", flags=re.UNICODE)
text = emoji_pattern.sub(r'', text)
if weibo_topic:
# text = re.sub(r"#\S+#", "", text) # 去除话题内容
# re.sub(r"#\S+\s?\S+#", "", "#ds e哈 oa#分发")
text = re.sub(r"#[^#]*?#","",text)
if linesep2space:
text = text.replace("\n", " ") # 不需要换行的时候变成1行
if deduplicate_space:
text = re.sub(r"(\s)+", r"", text) # 合并正文中过多的空格
# text = re.sub(r"(\s)+", r"\1", text) # 合并正文中过多的空格
# if t2s:
# cc = OpenCC('t2s')
# text = cc.convert(text)
assert hasattr(stop_terms, "__iter__"), Exception("去除的词语必须是一个可迭代对象")
if type(stop_terms) == str:
text = text.replace(stop_terms, "")
else:
for x in stop_terms:
text = text.replace(x, "")
if remove_puncts:
allpuncs = re.compile(
r"[~,\_《。》、?;:‘’"“”【「】」·!@¥…()—\,\<\.\>\/\?\;\:\'\"\[\]\{\}\~\`\!\@\#\$\%\^\&\*\(\)\-\=\+]")
text = re.sub(allpuncs, "", text)
return text.strip()