Как преобразовать языковой идентификатор IETF BCP 47 в ISO-639-2?
Я пишу серверный API для приложения iOS. Как часть процесса инициализации, приложение должно отправить язык интерфейса телефона на сервер через вызов API.
Проблема заключается в том, что Apple использует в своем языке что-то под названием IETF BCP 47. NSLocale preferredLanguages
функция
Возвращаемые значения имеют разную длину (например, [aa, ab, ace, ach, ada, ady, ae, af, afa, afh, agq, ...]
и я нашел очень мало парсеров, которые могут преобразовать этот код в правильный идентификатор языка.
Я хотел бы использовать более распространенный трехбуквенный языковой идентификатор ISO-639-2, который повсеместен, имеет много синтаксических анализаторов на многих языках и имеет стандартное трехбуквенное представление языков.
Как я могу преобразовать идентификатор языка IETF BCP 47 в трехбуквенный идентификатор языка ISO-639-2, предпочтительно в Python?
2 ответа
Идентификаторы BCP 47 начинаются с двухбуквенного кода языка ISO 639-1 или трехбуквенного кода 639-2, 639-3 или 639-5; см. раздел Синтаксис RFC 5646:
Language-Tag = langtag ; normal language tags / privateuse ; private use tag / grandfathered ; grandfathered tags langtag = language ["-" script] ["-" region] *("-" variant) *("-" extension) ["-" privateuse] language = 2*3ALPHA ; shortest ISO 639 code ["-" extlang] ; sometimes followed by ; extended language subtags / 4ALPHA ; or reserved for future use / 5*8ALPHA ; or registered language subtag
Я не ожидаю, что Apple будет использовать privateuse
или же grandfathered
формы, так что вы можете предположить, что вы смотрите здесь языковые коды ISO 639-1, ISO 639-2, ISO 639-3 или ISO 639-5. Просто сопоставьте 2-буквенные коды ISO-639-1 с 3-буквенными кодами ISO 639-*.
Вы можете использовать pycountry
пакет для этого:
import pycountry
lang = pycountry.languages.get(alpha2=two_letter_code)
three_letter_code = lang.terminology
Демо-версия:
>>> import pycountry
>>> lang = pycountry.languages.get(alpha2='aa')
>>> lang.terminology
u'aar'
где терминологическая форма является предпочтительным трехбуквенным кодом; Существует также библиографическая форма, которая отличается только для 22 записей. См. ISO 639-2 B и T коды. Пакет не включает записи из ISO 639-5, однако; этот список частично совпадает с 639-2, и я не думаю, что Apple вообще использует такие коды.
Из RFC5646 / BCP47:
Language-Tag = langtag ; normal language tags
/ privateuse ; private use tag
/ grandfathered ; grandfathered tags
langtag = language
["-" script]
["-" region]
*("-" variant)
*("-" extension)
["-" privateuse]
language = 2*3ALPHA ; shortest ISO 639 code
["-" extlang] ; sometimes followed by
; extended language subtags
/ 4ALPHA ; or reserved for future use
/ 5*8ALPHA ; or registered language subtag
privateuse = "x" 1*("-" (1*8alphanum))
grandfathered = irregular ; non-redundant tags registered
/ regular ; during the RFC 3066 era
Похоже, что первый сегмент большинства кодов BCP-47 должен быть действительными кодами ISO-639, хотя они могут не быть трехбуквенными вариантами. Код языка BCP-47 имеет несколько вариантов, которые не являются кодами ISO-639, а именно те, которые начинаются с x-
или же i-
а также ряд устаревших кодов, которые соответствуют grandfathered
часть грамматики:
irregular = "en-GB-oed" ; irregular tags do not match
/ "sgn-BE-FR" ; also includes i- prefixed codes
/ "sgn-BE-NL"
/ "sgn-CH-DE"
regular = "art-lojban" ; these tags match the 'langtag'
/ "cel-gaulish" ; production, but their subtags
/ "no-bok" ; are not extended language
/ "no-nyn" ; or variant subtags: their meaning
/ "zh-guoyu" ; is defined by their registration
/ "zh-hakka" ; and all of these are deprecated
/ "zh-min" ; in favor of a more modern
/ "zh-min-nan" ; subtag or sequence of subtags
/ "zh-xiang"
Хорошим началом было бы что-то вроде следующего:
def extract_iso_code(bcp_identifier):
language, _ = bcp_identifier.split('-', 1)
if 2 <= len(language) <=3:
# this is a valid ISO-639 code or is grandfathered
else:
# handle non-ISO codes
raise ValueError(bcp_identifier)
Преобразование из двухсимвольного варианта в трехсимвольный вариант должно быть достаточно простым для обработки, поскольку отображение хорошо известно.