2016-11-28 2 views
-1

У меня есть длинные списки человекочитаемых строк, некоторые из которых содержат несколько не-ASCII и даже нелатинских символов.Как преобразовать несколько произвольных строк в действительные идентификаторы, читаемые человеком?

'Count €' 
'Contains äüöß' 
'Y tu mamá también.' 
'что' 

Но сервис я использую требует, чтобы имена состоят только a-z, A-Z, 0-9, ., _, (пробел).

Что представляет собой сжатый способ преобразования их в уникальные имена, действующие в соответствии с этими требованиями?

Мы хотим как можно больше сохранить удобочитаемость. Например, в идеале не меняйте . на full stop, и не меняйте & на u38. И мы не можем просто отказаться от недопустимых символов или диакритических знаков. Например:

'Count euro symbol' 
'Contains a with umlaut u with umlaut o with umlaut sharp s' 
'Y tu mama_ tambie_n.' 
'cyrillic small letter che ...' 

Вот ограничения:
- должен быть Python (2 и 3)
- не должен требовать установки пакета
- должны сохранить uniquishness (это нормально, если есть крайние случаи, где он не делает)
- должно быть кратким

(Примечание:. 'Y tu mama tambien.' не был бы приемлем, учитывая вероятность нарушения uniquishness ограничения)

Есть несколько параллелей для превращения произвольных строк в допустимые имена классов или идентификаторы.

ответ

3

Googling «имена символов python» вызывает модуль unicodedata. Таким образом, одно место, чтобы начать что-то вроде

import string 
import unicodedata 

ALLOWED = set(string.ascii_letters + string.digits + '. _') 
sentences = ['Count €', 'Contains äüöß', 'Y tu mamá también.', 'что'] 

def encode(s): 
    return ''.join([unicodedata.name(c).replace(" ","_")+"_" 
        if c not in ALLOWED else c for c in s]) 

for s in sentences: 
    print(s) 
    print(encode(s)) 

, который дает мне

Count € 
Count EURO_SIGN_ 
Contains äüöß 
Contains LATIN_SMALL_LETTER_A_WITH_DIAERESIS_LATIN_SMALL_LETTER_U_WITH_DIAERESIS_LATIN_SMALL_LETTER_O_WITH_DIAERESIS_LATIN_SMALL_LETTER_SHARP_S_ 
Y tu mamá también. 
Y tu mamLATIN_SMALL_LETTER_A_WITH_ACUTE_ tambiLATIN_SMALL_LETTER_E_WITH_ACUTE_n. 
что 
CYRILLIC_SMALL_LETTER_CHE_CYRILLIC_SMALL_LETTER_TE_CYRILLIC_SMALL_LETTER_O_ 

С помощью всего лишь немного больше работы (выбирая соответствующий разделитель для побега) вы можете гарантировать, что это может быть круглым споткнулся отлично, но это остается как упражнение для читателя.

+0

Большое спасибо. В настоящее время у меня есть что-то похожее на это, используя 'unicode.name', но ваша формулировка более чистая и более сжатая. Я все еще надежду на один лайнер. –

+0

@ A.M.Bittlingmayer: это глупо. Мы разработчики (предположительно), а не профессиональные кодовые игроки. Во всяком случае, вышеприведенный код слишком ** короткий **: у него нет документации, он не работает в оба конца и так далее. Я бы отказался от кода, который я представил в обзоре кода, и завязал разговор с тем, кто его совершил! – DSM

+0

Я не собираюсь запутывать его, но, возможно, есть умный способ сделать это чисто или существующий lib. Посмотрим. –

Смежные вопросы