code

str.translate를 유니 코드 문자열과 함께 사용하려면 어떻게해야합니까?

codestyles 2020. 12. 31. 08:18
반응형

str.translate를 유니 코드 문자열과 함께 사용하려면 어떻게해야합니까?


다음 코드가 있습니다.

import string
def translate_non_alphanumerics(to_translate, translate_to='_'):
    not_letters_or_digits = u'!"#%\'()*+,-./:;<=>?@[\]^_`{|}~'
    translate_table = string.maketrans(not_letters_or_digits,
                                       translate_to
                                         *len(not_letters_or_digits))
    return to_translate.translate(translate_table)

유니 코드가 아닌 문자열에 적합합니다.

>>> translate_non_alphanumerics('<foo>!')
'_foo__'

그러나 유니 코드 문자열에는 실패합니다.

>>> translate_non_alphanumerics(u'<foo>!')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in translate_non_alphanumerics
TypeError: character mapping must return integer, None or unicode

str.translate () 메서드 에 대한 Python 2.6.2 문서 의 "유니 코드 객체"에 대한 단락을 이해할 수 없습니다 .

유니 코드 문자열에 대해 어떻게 작동합니까?


유니 코드 버전의 translate는 유니 코드 서수 (를 사용하여 단일 문자에 대해 검색 할 수 있음)에서 유니 코드 서 수로의 매핑이 필요합니다 ord. 문자를 삭제하려면에 매핑합니다 None.

모든 문자의 서수를 번역하려는 서수에 매핑하는 사전을 작성하도록 함수를 변경했습니다.

def translate_non_alphanumerics(to_translate, translate_to=u'_'):
    not_letters_or_digits = u'!"#%\'()*+,-./:;<=>?@[\]^_`{|}~'
    translate_table = dict((ord(char), translate_to) for char in not_letters_or_digits)
    return to_translate.translate(translate_table)

>>> translate_non_alphanumerics(u'<foo>!')
u'_foo__'

편집 : 번역 매핑은 유니 코드 서수 (를 통해 ord)에서 다른 유니 코드 서수, 유니 코드 문자열 또는 없음 (삭제)으로 매핑되어야합니다 . 따라서 translate_to유니 코드 리터럴이되도록 기본값을 변경했습니다 . 예를 들면 :

>>> translate_non_alphanumerics(u'<foo>!', u'bad')
u'badfoobadbad'

이 버전에서는 상대적으로 다른 사람에게 편지를 보낼 수 있습니다.

def trans(to_translate):
    tabin = u'привет'
    tabout = u'тевирп'
    tabin = [ord(char) for char in tabin]
    translate_table = dict(zip(tabin, tabout))
    return to_translate.translate(translate_table)

원래 함수 와 유니 코드 및 ASCII 문자열과 함께 작동하는 Mike 버전 의 다음 조합을 생각해 냈습니다 .

def translate_non_alphanumerics(to_translate, translate_to=u'_'):
    not_letters_or_digits = u'!"#%\'()*+,-./:;<=>?@[\]^_`{|}~'
    if isinstance(to_translate, unicode):
        translate_table = dict((ord(char), unicode(translate_to))
                               for char in not_letters_or_digits)
    else:
        assert isinstance(to_translate, str)
        translate_table = string.maketrans(not_letters_or_digits,
                                           translate_to
                                              *len(not_letters_or_digits))
    return to_translate.translate(translate_table)

업데이트 : "강제" translate_to를 유니 코드에 대한 유니 코드로 지정 translate_table합니다. 감사합니다 Mike.


str 및 unicode 객체 모두에서 작동하는 간단한 해킹의 경우 translate ()를 실행하기 전에 변환 테이블을 유니 코드로 변환하십시오.

import string
def translate_non_alphanumerics(to_translate, translate_to='_'):
    not_letters_or_digits = u'!"#%\'()*+,-./:;<=>?@[\]^_`{|}~'
    translate_table = string.maketrans(not_letters_or_digits,
                                       translate_to
                                         *len(not_letters_or_digits))
    translate_table = translate_table.decode("latin-1")
    return to_translate.translate(translate_table)

The catch here is that it will implicitly convert all str objects to unicode, throwing errors if to_translate contains non-ascii characters.


Instead of having to specify all the characters that need to be replaced, you could also view it the other way around and, instead, specify only the valid characters, like so:

import re

def replace_non_alphanumerics(source, replacement_character='_'):
    result = re.sub("[^_a-zA-Z0-9]", replacement_character, source)

    return result

This works with unicode as well as regular strings, and preserves the type (if both the replacement_character and the source are of the same type, obviously).


I found that where in python 2.7, with type str, you would write

import string
table = string.maketrans("123", "abc")
print "135".translate(table)

whereas with type unicode you would say

table = {ord(s): unicode(d) for s, d in zip("123", "abc")}
print u"135".translate(table)

In python 3.6 you would write

table = {ord(s): d for s, d in zip("123", "abc")}
print("135".translate(table))

maybe this is helpful.

ReferenceURL : https://stackoverflow.com/questions/1324067/how-do-i-get-str-translate-to-work-with-unicode-strings

반응형