Простой вопрос, без реального простого ответа. Суть в том, что все компьютеры действительно «понимают», это двоичные инструкции, в которые «быстрые» языки, такие как C, компилируются.
Кроме того, существуют виртуальные машины, которые понимают разные двоичные инструкции (например, Java и .NET), но их нужно переводить на лету в машинные инструкции с помощью Just-In-Compiler (JIT). Это почти так же быстро (даже быстрее в некоторых конкретных случаях, потому что JIT имеет больше информации, чем статический компилятор о том, как используется код.)
Затем существуют интерпретируемые языки, которые обычно также имеют свои промежуточные бинарные инструкции, но интерпретатор функционирует во многом как цикл с большим оператором switch, в котором указывается регистр для каждой инструкции и как ее выполнять. Этот уровень абстракции над основным машинным кодом является медленным. В интерпретаторе задействовано больше инструкций, длинные цепочки вызовов функций для выполнения даже простых задач, и можно утверждать, что в результате память и кэш не используются так эффективно.
Но интерпретируемые языки часто бывают достаточно быстрыми для тех целей, для которых они используются. Веб-приложения неизменно связаны IO (обычно доступом к базе данных), который на порядок медленнее, чем любой интерпретатор.
Взгляните на эту ссылку [отредактировано]
Вот код со страницы
def latin1_to_ascii (unicrap):
"""This replaces UNICODE Latin-1 characters with
something equivalent in 7-bit ASCII. All characters in the standard
7-bit ASCII range are preserved. In the 8th bit range all the Latin-1
accented letters are stripped of their accents. Most symbol characters
are converted to something meaningful. Anything not converted is deleted.
"""
xlate = {
0xc0:'A', 0xc1:'A', 0xc2:'A', 0xc3:'A', 0xc4:'A', 0xc5:'A',
0xc6:'Ae', 0xc7:'C',
0xc8:'E', 0xc9:'E', 0xca:'E', 0xcb:'E',
0xcc:'I', 0xcd:'I', 0xce:'I', 0xcf:'I',
0xd0:'Th', 0xd1:'N',
0xd2:'O', 0xd3:'O', 0xd4:'O', 0xd5:'O', 0xd6:'O', 0xd8:'O',
0xd9:'U', 0xda:'U', 0xdb:'U', 0xdc:'U',
0xdd:'Y', 0xde:'th', 0xdf:'ss',
0xe0:'a', 0xe1:'a', 0xe2:'a', 0xe3:'a', 0xe4:'a', 0xe5:'a',
0xe6:'ae', 0xe7:'c',
0xe8:'e', 0xe9:'e', 0xea:'e', 0xeb:'e',
0xec:'i', 0xed:'i', 0xee:'i', 0xef:'i',
0xf0:'th', 0xf1:'n',
0xf2:'o', 0xf3:'o', 0xf4:'o', 0xf5:'o', 0xf6:'o', 0xf8:'o',
0xf9:'u', 0xfa:'u', 0xfb:'u', 0xfc:'u',
0xfd:'y', 0xfe:'th', 0xff:'y',
0xa1:'!', 0xa2:'{cent}', 0xa3:'{pound}', 0xa4:'{currency}',
0xa5:'{yen}', 0xa6:'|', 0xa7:'{section}', 0xa8:'{umlaut}',
0xa9:'{C}', 0xaa:'{^a}', 0xab:'<<', 0xac:'{not}',
0xad:'-', 0xae:'{R}', 0xaf:'_', 0xb0:'{degrees}',
0xb1:'{+/-}', 0xb2:'{^2}', 0xb3:'{^3}', 0xb4:"'",
0xb5:'{micro}', 0xb6:'{paragraph}', 0xb7:'*', 0xb8:'{cedilla}',
0xb9:'{^1}', 0xba:'{^o}', 0xbb:'>>',
0xbc:'{1/4}', 0xbd:'{1/2}', 0xbe:'{3/4}', 0xbf:'?',
0xd7:'*', 0xf7:'/'
}
r = ''
for i in unicrap:
if xlate.has_key(ord(i)):
r += xlate[ord(i)]
elif ord(i) >= 0x80:
pass
else:
r += i
return r
# This gives an example of how to use latin1_to_ascii().
# This creates a string will all the characters in the latin-1 character set
# then it converts the string to plain 7-bit ASCII.
if __name__ == '__main__':
s = unicode('','latin-1')
for c in range(32,256):
if c != 0x7f:
s = s + unicode(chr(c),'latin-1')
print 'INPUT:'
print s.encode('latin-1')
print
print 'OUTPUT:'
print latin1_to_ascii(s)
Метод translate позволяет удалять символы. Вы можете использовать это для удаления произвольных символов.
Fullname.translate(None,"'-\"")
Если вы хотите удалить целые классы символов, вы можете использовать модуль re.
re.sub('[^a-z0-9 ]', '', Fullname.strip().lower(),)
Я бы сделал что-то вроде этого
# coding=utf-8
def alnum_dot(name, replace={}):
import re
for k, v in replace.items():
name = name.replace(k, v)
return re.sub("[^a-z.]", "", name.strip().lower())
print alnum_dot(u"Frédrik Holmström", {
u"ö":"o",
" ":"."
})
Второй аргумент - это символы, которые вы хотите заменить, все не az и. символы, которые не заменяются, будут удалены
Следующая функция является общей:
import unicodedata
def not_combining(char):
return unicodedata.category(char) != 'Mn'
def strip_accents(text, encoding):
unicode_text= unicodedata.normalize('NFD', text.decode(encoding))
return filter(not_combining, unicode_text).encode(encoding)
# in a cp1252 environment
>>> print strip_accents("déjà", "cp1252")
deja
# in a cp1253 environment
>>> print strip_accents("καλημέρα", "cp1253")
καλημερα
Очевидно, вы должны знать кодировку своих строк.
Если вы не боитесь устанавливать сторонние модули, то обратите внимание на порт python модуля Perl Text :: Unidecode
(он также на pypi ).
Модуль не делает ничего, кроме использования таблицы поиска для транслитерации символов. Я просмотрел код, он выглядит очень просто. Поэтому я полагаю, что он работает практически с любой ОС и с любой версией Python (crossfingers). Его также легко связать с вашим приложением.
С помощью этого модуля вам не нужно создавать таблицу поиска вручную (= снижается риск того, что она будет неполной).
Преимущество этого модуля по сравнению с техникой нормализации Unicode заключается в это: нормализация Unicode не заменяет все символы. Хороший пример - такой символ, как «æ». При нормализации Unicode это будет «Буква в нижнем регистре» (Ll). Это означает, что использование метода normalize
не даст вам ни символа замены, ни полезной подсказки. К сожалению, этот символ не может быть представлен в ASCII. Так что вы получите ошибки.
Упомянутый модуль лучше справляется с этой задачей. Фактически это заменит "æ" на "ae". Это действительно полезно и имеет смысл.
Самая впечатляющая вещь, которую я видел, - это то, что это идет намного дальше. Он даже заменяет японские символы Кана в основном должным образом. Например, он заменяет «は» на «ха». Что совершенно нормально. Это небезопасно, поскольку текущая версия заменяет «ち» на «ti» вместо «chi». Так что вы' Придется обращаться с этим с осторожностью для более экзотических символов.
Использование модуля простое ::
from unidecode import unidecode
var_utf8 = "æは".decode("utf8")
unidecode( var_utf8 ).encode("ascii")
>>> "aeha"
Обратите внимание, что я не имею никакого отношения к этому модулю напрямую. Так получилось, что я нахожу это очень полезным.
Edit: Патч, который я отправил, исправил ошибку, касающуюся японской каны. Я починил только ту, которую смог сразу заметить. Возможно, я кое-что пропустил.