code

파이썬의 문자열에서 인쇄 할 수없는 문자 제거

codestyles 2020. 10. 7. 07:39
반응형

파이썬의 문자열에서 인쇄 할 수없는 문자 제거


나는 달리는 데 사용

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

Perl에서 인쇄 할 수없는 문자를 제거합니다.

파이썬에는 POSIX 정규식 클래스가 없으며 내가 원하는 것을 의미하는 [: print :]를 작성할 수 없습니다. 나는 파이썬에서 문자가 인쇄 가능한지 아닌지를 감지하는 방법을 모른다.

당신은 무엇을 하시겠습니까?

편집 : 유니 코드 문자도 지원해야합니다. string.printable 방법은 출력에서 ​​행복하게 제거합니다. curses.ascii.isprint는 모든 유니 코드 문자에 대해 false를 반환합니다.


불행히도 파이썬에서는 문자열을 반복하는 것이 다소 느립니다. 정규 표현식은 이런 종류의 일보다 훨씬 더 빠릅니다. 캐릭터 클래스를 직접 구축하면됩니다. 한편 UnicodeData 모듈은 특히이에 매우 도움이된다 unicodedata.category () 함수입니다. 범주에 대한 설명은 유니 코드 문자 데이터베이스참조하십시오 .

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)

내가 아는 한, 가장 비단뱀적이고 효율적인 방법은 다음과 같습니다.

import string

filtered_string = filter(lambda x: x in string.printable, myStr)

다음 unicodedata.category()기능을 사용하여 필터를 설정할 수 있습니다.

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

사용 가능한 범주 유니 코드 데이터베이스 문자 속성 에서 175 페이지의 표 4-9를 참조하십시오.


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})

.translate ()가 regex 및 .replace ()와 어떻게 비교되는지에 대해서는 구두점 제거에 대한 이 StackOverflow 게시물을 참조하십시오.


이 함수는 목록 이해력과 str.join을 사용하므로 O (n ^ 2) 대신 선형 시간으로 실행됩니다.

from curses.ascii import isprint

def printable(input):
    return ''.join(char for char in input if isprint(char))

내가 지금 생각 해낸 최고는 (위의 python-izers 덕분에)

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

이것은 유니 코드 문자 / 문자열에서 작동하는 유일한 방법입니다.

더 나은 옵션이 있습니까?


아래는 위의 다른 것보다 성능이 더 빠릅니다. 구경하다

''.join([x if x in string.printable else '' for x in Str])

Python에는 POSIX 정규식 클래스가 없습니다.

regex라이브러리를 사용할 때 : https://pypi.org/project/regex/

잘 관리되고 유니 코드 정규식, Posix 정규식 등을 지원합니다. 사용법 (메소드 서명)입니다 매우 파이썬의 유사합니다 re.

문서에서 :

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

POSIX character classes are supported. These are normally treated as an alternative form of \p{...}.

(I'm not affiliated, just a user.)


Yet another option in python 3:

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

The following will work with Unicode input and is rather fast...

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('') == ''

My own testing suggests this approach is faster than functions that iterate over the string and return a result using str.join.


To remove 'whitespace',

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))

참고URL : https://stackoverflow.com/questions/92438/stripping-non-printable-characters-from-a-string-in-python

반응형