我正在做一个中国的NLP项目。我需要删除除数字之间的那些字符以外的所有标点符号,并且只保留汉字(\u4e00-\u9fff)、字母数字字符(0-9a-Za-Z).For示例,应保留12-34中的连字符,而删除123后的等号。
这是我的python脚本。
import re
s = "中国,中,。》%国foo中¥国bar@中123=国%中国12-34中国"
res = re.sub(u'(?<=[^0-9])[^\u4e00-\u9fff0-9a-zA-Z]+(?=[^0-9])','',s)
print(res)预期的产出应该是
中国中国foo中国bar中123国中国12-34中国但结果是
中国中国foo中国bar中123=国中国12-34中国我不明白为什么输出中有额外的等号?
发布于 2017-04-05 19:20:46
您的正则表达式将首先检查"="和[^\u4e00-\u9fff0-9a-zA-Z]+。这会成功的。然后,它将检查查找和展望,这必须是两个失败。如果其中一个成功了,这个角色就会保留下来。这意味着您的代码实际上保存了任何非字母数字,非中文字符,其中的数字在任何一边。
您可以尝试以下正则表达式:
u'([\u4e00-\u9fff0-9a-zA-Z]|(?<=[0-9])[^\u4e00-\u9fff0-9a-zA-Z]+(?=[0-9]))'您可以这样使用它:
import re
s = "中国,中,。》%国foo中¥国bar@中123=国%中国12-34中国"
res = re.findall(u'([\u4e00-\u9fff0-9a-zA-Z]|(?<=[0-9])[^\u4e00-\u9fff0-9a-zA-Z]+(?=[0-9]))',s)
print(res.join(''))发布于 2017-04-05 19:21:22
我建议在数字之间匹配和捕获这些字符(以便稍后在输出中恢复它们),并且只在其他上下文中匹配它们。
在Python 2中,它看起来像
import re
s = u"中国,中,。》%国foo中¥国bar@中123=国%中国12-34中国"
pat_block = u'[^\u4e00-\u9fff0-9a-zA-Z]+';
pattern = u'([0-9]+{0}[0-9]+)|{0}'.format(pat_block)
res = re.sub(pattern, lambda x: x.group(1) if x.group(1) else u"" ,s)
print(res.encode("utf8")) # => 中国中国foo中国bar中123国中国12-34中国见Python演示
如果需要在任何Unicode数字中保留这些符号,则需要将[0-9]替换为\d,并将re.UNICODE标志传递给regex。
regex看起来就像
([0-9]+[^\u4e00-\u9fff0-9a-zA-Z]+[0-9]+)|[^\u4e00-\u9fff0-9a-zA-Z]+它的工作方式如下:
([0-9]+[^\u4e00-\u9fff0-9a-zA-Z]+[0-9]+) -第1组捕获[0-9]+ - 1+数字[^\u4e00-\u9fff0-9a-zA-Z]+ - 1+字符(在指定范围内定义的字符除外)[0-9]+ - 1+数字
| -或[^\u4e00-\u9fff0-9a-zA-Z]+ - 1+字符(在指定范围内定义的字符除外)在Python2.x中,当一个组在re.sub中不匹配时,对它的反向引用为None,这就是为什么需要lambda表达式来检查group 1是否首先匹配。
https://stackoverflow.com/questions/43239462
复制相似问题