如何查找給定字元編碼的語言環境名稱?
的手冊頁
setlocale
似乎說語言程式碼和字元編碼名稱足以設置適當的語言環境:語言環境名稱通常採用語言形式
$$ _territory $$$$ .codeset $$$$ @modifier $$,其中語言是 ISO 639 語言程式碼,地區是 ISO 3166 國家程式碼,程式碼集是字元集或編碼標識符,如 ISO-8859-1 或 UTF-8。
但是,一個快速測試表明,只有語言環境名稱的“修飾符”部分是可選的:
void tryLocale(const char * locid) { char * result = std::setlocale(LC_CTYPE, locid); std::cout << locid << " = " << (result ? result : "fail") << std::endl; } int main() { tryLocale("de"); // de = fail tryLocale("de_DE"); // de_DE = fail tryLocale("de_DE.CP1252"); // de_DE.CP1252 = de_DE.CP1252 tryLocale("de.CP1252"); // de.CP1252 = fail tryLocale(".CP1252"); // .CP1252 = fail }
我的問題是我只知道所需的編碼名稱(例如
ISO-8859-1
),我可能會想出語言程式碼(例如en
)。我不知道如何找到一個合適的國家名稱(例如US
),而且我對一個國家也不感興趣:我只希望tolower
我的應用程序中的功能使用正確的程式碼頁。
我認為您將不得不遍歷它們。在
zsh
:for l (${(f)"$(locale -a)"}) [[ $(LC_ALL=$l locale charmap) = ISO-8859-1 ]] && print -r -- $l
或者在模組中使用其
$langinfo
特殊的關聯數組zsh/langinfo
:zmodload zsh/langinfo for LC_ALL (${(f)"$(locale -a)"}) [[ $langinfo[CODESET] = ISO-8859-1 ]] && print -r -- $LC_ALL
將列出所有使用 ISO-8859-1 作為charmap 的可用語言環境。
但請注意,
LC_CTYPE
指定charmap / codeset 的類別還包括字元分類:什麼是小寫字母,什麼是標點符號等以及音譯(如 所使用的tolower()
),兩者都可能因地區/國家而異下一個即使使用相同的程式碼集。例如,查看 GNU 土耳其語語言環境中的小寫字母如何
I
,ı
無論使用什麼字元映射(UTF-8、ISO-8859-9…),而i
在大多數其他也使用 UTF-8 的語言環境中。您可以查看語言環境源定義,例如:
(cd /usr/share/i18n/locales && pcregrep -Me '(?ms)^LC_CTYPE.*?^END' -- *)
在 GNU 系統上查看該
LC_CTYPE
類別跨區域設置的差異。您不會在其中找到charmap,這些文件和charmaps 組合的區域設置是使用生成的localedef -i thosefiles -f charmap
,儘管只有一些組合有意義,請參閱/usr/share/i18n/SUPPORTED
列表。例如,
en_GB
您系統上的語言環境可能是使用 生成的,localedef -i locales/en_GB -f charmaps/ISO-8859-1.gz
而en_GB.UTF-8
使用localedef -i locales/en_GB -f charmaps/UTF-8.gz
.因此,在這裡,也許您需要找到一個
ISO-8859-1
用作charmap 的語言環境,但還需要具有在英國大陸對英國英語或在意大利/德國等講德語的人有意義的音譯規則和字元分類,例如滿足:[[ $(locale language) = 'British English' && $(locale territory) = 'United Kingdom' && $(locale charmap) = ISO-8859-1 ]]
這應該會稍微縮小選擇範圍。
請注意,
language
andterritory
是非標準的 GNU 擴展,這就解釋了為什麼你不會在 zsh 中找到它們$langinfo
。GNU libc 文件 (info libc langinfo
) 僅提及:文件“langinfo.h”定義了更多的符號,但沒有一個是官方的。使用它們是不可移植的,並且返回值的格式可能會改變。因此,我們建議(原文如此)您不要使用它們。
/usr/include/langinfo.h
在我的系統上有:_NL_IDENTIFICATION_LANGUAGE, _NL_IDENTIFICATION_TERRITORY,
另請參閱
locale -k LC_IDENTIFICATION
,locale -k LC_CTYPE
以獲得 GNU 系統上給定語言環境類別支持的關鍵字列表(locale -kc LC_ALL
過去可以使用,但現在顯然不再使用)。