代码之家  ›  专栏  ›  技术社区  ›  Vinko Vrsalovic

从python中的字符串中剥离不可打印的字符

  •  75
  • Vinko Vrsalovic  · 技术社区  · 16 年前

    我用来跑步

    $s =~ s/[^[:print:]]//g;
    

    在Perl上去掉不可打印的字符。

    在Python中没有posix regex类,我无法编写[:print:]我不知道在python中如何检测字符是否可打印。

    你会怎么做?

    编辑:它还必须支持Unicode字符。string.printable方法会很高兴地将它们从输出中剥离出来。 curses.ascii.isprint将为任何Unicode字符返回false。

    11 回复  |  直到 16 年前
        1
  •  70
  •   Russ Chris    12 年前

    不幸的是,在Python中迭代字符串的速度相当慢。正则表达式对于这种类型的东西来说速度超过了一个数量级。你只需要自己建立角色类。这个 单播数据 模块对此非常有用,尤其是 unicodedata.category()。 功能。见 Unicode Character Database 对于类别的描述。

    import unicodedata, re
    
    all_chars = (unichr(i) for i in xrange(0x110000))
    control_chars = ''.join(c for c in all_chars if unicodedata.category(c) == 'Cc')
    # or equivalently and much more efficiently
    control_chars = ''.join(map(unichr, range(0,32) + range(127,160)))
    
    control_char_re = re.compile('[%s]' % re.escape(control_chars))
    
    def remove_control_chars(s):
        return control_char_re.sub('', s)
    
        2
  •  60
  •   zmo    10 年前

    据我所知,最有效的方法是:

    import string
    
    filtered_string = filter(lambda x: x in string.printable, myStr)
    
        3
  •  9
  •   Community pid    7 年前

    在Python 3中,

    def filter_nonprintable(text):
        import string
        # Get the difference of all ASCII characters from the set of printable characters
        nonprintable = set([chr(i) for i in range(128)]).difference(string.printable)
        # Use translate to remove all non-printable characters
        return text.translate({ord(character):None for character in nonprintable})
    

    this StackOverflow post on removing punctuation 有关.translate()与regex&的比较方式,请替换()。

        4
  •  8
  •   kaleissin    8 年前

    您可以尝试使用 unicodedata.category() 功能:

    printable = Set('Lu', 'Ll', ...)
    def filter_non_printable(str):
      return ''.join(c for c in str if unicodedata.category(c) in printable)
    

    Unicode database character properties 对于可用类别

        5
  •  5
  •   rmmh CJ Cullen    13 年前

    此函数使用列表理解和str.join,因此它以线性时间而不是o(n^2)运行:

    from curses.ascii import isprint
    
    def printable(input):
        return ''.join(char for char in input if isprint(char))
    
        6
  •  2
  •   Vinko Vrsalovic    16 年前

    我现在想到的最好的方法是(感谢上面的python-izers)

    def filter_non_printable(str):
      return ''.join([c for c in str if ord(c) > 31 or ord(c) == 9])
    

    这是我发现的唯一适用于Unicode字符/字符串的方法

    有更好的选择吗?

        7
  •  1
  •   Nilav Baran Ghosh    7 年前

    下面的一个比上面的其他的快。看一看

    ''.join([x if x in string.printable else '' for x in Str])
    
        8
  •  1
  •   Risadinha    6 年前

    在python中没有posix regex类

    使用时有 regex 图书馆: https://pypi.org/project/regex/

    它维护良好,支持unicode regex、posix regex等等。用法(方法签名)是 非常 类似于巨蟒 re .

    从文档中:

    [[:alpha:]]; [[:^alpha:]]

    支持POSIX字符类。这些 通常被视为 \p{...} .

    (我没有附属关系,只是一个用户。)

        9
  •  0
  •   knowingpark    7 年前

    要删除“空白”,

    import re
    t = """
    \n\t<p>&nbsp;</p>\n\t<p>&nbsp;</p>\n\t<p>&nbsp;</p>\n\t<p>&nbsp;</p>\n\t<p>
    """
    pat = re.compile(r'[\t\n]')
    print(pat.sub("", t))
    
        10
  •  0
  •   ChrisP    6 年前

    下面将使用Unicode输入,而且速度相当快…

    import sys
    
    # build a table mapping all non-printable characters to None
    NOPRINT_TRANS_TABLE = {
        i: None for i in range(0, sys.maxunicode + 1) if not chr(i).isprintable()
    }
    
    def make_printable(s):
        """Replace non-printable characters in a string."""
    
        # the translate method on str removes characters
        # that map to None from the string
        return s.translate(NOPRINT_TRANS_TABLE)
    
    
    assert make_printable('Café') == 'Café'
    assert make_printable('\x00\x11Hello') == 'Hello'
    assert make_printable('') == ''
    

    我自己的测试表明,这种方法比迭代字符串并使用 str.join .

        11
  •  -1
  •   Alex Myers    6 年前

    python 3中的另一个选项是:

    re.sub(f'[^{re.escape(string.printable)}]', '', my_string)
    
    推荐文章