특정 문자 인코딩에 대한 로케일 이름을 찾는 방법은 무엇입니까?

특정 문자 인코딩에 대한 로케일 이름을 찾는 방법은 무엇입니까?

매뉴얼 페이지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내 애플리케이션의 기능과 같은 기능이 올바른 코드 페이지를 사용하기를 원할 뿐입니다.

답변1

나는 당신이 그들을 순환해야한다고 생각합니다. 존재하다 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을 문자표로 사용하는 사용 가능한 모든 로캘이 나열됩니다.

그러나 LC_CTYPE문자 맵/코드 세트를 지정하는 범주에는 문자 분류(소문자, 구두점 등)와 음역(사용된 대로)도 포함되며 tolower()둘 다 지역/국가에 따라 다를 수 있습니다. 동일한 코드 세트를 사용하더라도 다음 코드도 마찬가지입니다.

예를 들어, 사용된 문자 매핑(UTF-8, ISO-8859-9...)에 관계없이 GNU 터키어 로케일의 소문자 형식을 살펴보고 IUTF -8을 사용하는 대부분의 다른 로케일에서도 마찬가지입니다.ıi

다음과 같은 로케일 소스 정의를 볼 수 있습니다.

(cd /usr/share/i18n/locales && pcregrep -Me '(?ms)^LC_CTYPE.*?^END' -- *)

GNU 시스템의 이 범주에서 LC_CTYPE로케일 간 차이점을 확인하세요. 여기서는 문자 맵을 찾을 수 없습니다. 이러한 파일 조합에 대한 로케일과 문자 맵은 를 사용하여 생성됩니다 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영국 영어 또는 이탈리아어/독일어와 같은 독일어 사용자가 영국 본토에서 이해할 수 있는 음역 규칙 및 문자 분류도 필요합니다.

[[ $(locale language)  = 'British English' &&
   $(locale territory) = 'United Kingdom' &&
   $(locale charmap)   = ISO-8859-1 ]]

이렇게 하면 선택 범위가 약간 좁아집니다.

language및 는 territory비표준 GNU 확장입니다. 이는 zsh( ) $langinfo에 대한 .GNU libc 문서에서 다음만 언급하는 이유를 설명합니다.info libc langinfo

"langinfo.h" 파일에는 더 많은 기호가 정의되어 있지만 공식적인 기호는 없습니다. 이를 사용하는 것은 이식 가능하지 않으며 반환 값의 형식이 변경될 수 있습니다. 그러므로 우리는 당신이 그것들을 사용하지 않는 것을 권장합니다.

/usr/include/langinfo.h내 시스템에는 다음이 있습니다.

  _NL_IDENTIFICATION_LANGUAGE,
  _NL_IDENTIFICATION_TERRITORY,

GNU 시스템에서 특정 로케일 범주에 대해 지원되는 키워드 목록 도 참조하십시오 locale -k LC_IDENTIFICATION( 이전에는 작동했지만 더 이상 작동하지 않는 것 같습니다).locale -k LC_CTYPElocale -kc LC_ALL

관련 정보