从Unicode格式的字符串中删除标点符号

acp*_*eon 40 python unicode

我有一个函数,从字符串列表中删除标点符号:

def strip_punctuation(input):
    x = 0
    for word in input:
        input[x] = re.sub(r'[^A-Za-z0-9 ]', "", input[x])
        x += 1
    return input
Run Code Online (Sandbox Code Playgroud)

我最近修改了我的脚本以使用Unicode字符串,所以我可以处理其他非西方字符.当遇到这些特殊字符并且只返回空的Unicode字符串时,此函数会中断.如何从Unicode格式的字符串中可靠地删除标点符号?

jfs*_*jfs 73

你可以使用unicode.translate()方法:

import unicodedata
import sys

tbl = dict.fromkeys(i for i in xrange(sys.maxunicode)
                      if unicodedata.category(unichr(i)).startswith('P'))
def remove_punctuation(text):
    return text.translate(tbl)
Run Code Online (Sandbox Code Playgroud)

你也可以使用regex模块r'\p{P}'支持的:

import regex as re

def remove_punctuation(text):
    return re.sub(ur"\p{P}+", "", text)
Run Code Online (Sandbox Code Playgroud)

  • +1表示正则表达式 - 这是_the_方式去这里.值得注意的是,它是非标准的(尚未)并且必须单独安装.此外,在py2中,您需要将模式设置为unicode("ur".."`)以切换unicode匹配模式. (8认同)
  • @posdef它是Python 2代码(阅读第一条评论).在Python 3上的'r''之前删除'u''`前缀或使用`u"\\ p {P} +"`(在这种情况下你必须手动逃避反冲). (3认同)
  • `re` 模块(不是 `regex`)似乎不支持 `\p{P}`,是吗? (2认同)

met*_*mit 19

如果你想在Python 3中使用JF Sebastian的解决方案:

import unicodedata
import sys

tbl = dict.fromkeys(i for i in range(sys.maxunicode)
                      if unicodedata.category(chr(i)).startswith('P'))
def remove_punctuation(text):
    return text.translate(tbl)
Run Code Online (Sandbox Code Playgroud)


Dae*_*yth 8

您可以使用unicodedata模块的category函数遍历字符串,以确定字符是否为标点符号.

有关可能的输出category,请参阅unicode.org关于常规类别值的文档

import unicodedata.category as cat
def strip_punctuation(word):
    return "".join(char for char in word if cat(char).startswith('P'))
filtered = [strip_punctuation(word) for word in input]
Run Code Online (Sandbox Code Playgroud)

此外,请确保您正确处理编码和类型.这个演示文稿是一个很好的起点:http://bit.ly/unipain

  • 这个答案中有一个小但重要的错误: strip_punctuation 实际上与您的意图相反,并且只会返回标点符号,因为您在理解中忘记了“not”。我会编辑答案来修复它,但“编辑必须至少有 6 个字符”除外。 (2认同)

Fac*_*sco 7

基于Daenyth答案的简短版本

import unicodedata

def strip_punctuation(text):
    """
    >>> strip_punctuation(u'something')
    u'something'

    >>> strip_punctuation(u'something.,:else really')
    u'somethingelse really'
    """
    punctutation_cats = set(['Pc', 'Pd', 'Ps', 'Pe', 'Pi', 'Pf', 'Po'])
    return ''.join(x for x in text
                   if unicodedata.category(x) not in punctutation_cats)

input_data = [u'somehting', u'something, else', u'nothing.']
without_punctuation = map(strip_punctuation, input_data)
Run Code Online (Sandbox Code Playgroud)