LC_COLLATE(반드시)가 문자 범위에 영향을 줍니까?

LC_COLLATE(반드시)가 문자 범위에 영향을 줍니까?

정돈하다order through는 LC_COLLATE개별 문자의 정렬 순서를 정의할 뿐만 아니라 문자 범위의 의미도 정의합니다. 아니면 그럴까요? 다음 스니펫을 고려하세요.

unset LANGUAGE LC_ALL
echo B | LC_COLLATE=en_US grep '[a-z]'

직관적으로 Bis is not in [a-z]이므로 아무 것도 출력해서는 안 됩니다. 이것이 Ubuntu 8.04 또는 10.04에서 발생하는 현상입니다. 그러나 데비안 lenny 또는 squeeze를 실행하는 일부 컴퓨터에서는 범위에 대문자를 포함하여 B데이터 정렬 안과 사이의 a-z모든 항목이 포함된다는 것을 알 수 있습니다.azBZ

테스트된 모든 시스템에는 en_US로케일이 생성되었습니다. 나는 또한 로케일을 변경해 보았습니다. B위의 일치하는 기계 에서 이것은 {en_{AU,CA,GB,IE,US},fr_FR,it_IT,es_ES,de_DE}{iso8859-1,iso8859-15,utf-8}일본어(사용 가능한 인코딩) 및 /를 제외하고 .CPOSIX

정규식에서 문자 범위는 무엇을 의미합니까?, 언제 ASCII를 능가할 것인가? 일부 Debian 설치와 다른 Debian 설치 및 Ubuntu 사이에 차이점이 있는 이유는 무엇입니까? 다른 시스템은 어떻게 작동하나요? 누가 옳고 누가 버그를 보고해야 합니까?

[a-z](주로 GNU libc 기반 시스템 에서 로케일 과 같은 문자 범위의 동작에 대해 구체적으로 묻는 것입니다 en_US. 소문자 또는 ASCII 소문자를 일치시키는 방법을 묻는 것이 아닙니다.)


두 대의 Debian 시스템에서 하나는 B켜지고 [a-z]하나는 꺼지면 출력은 다음 LC_COLLATE=en_US locale -k LC_COLLATE과 같습니다.

collate-nrules=4
collate-rulesets=""
collate-symb-hash-sizemb=1
collate-codeset="ISO-8859-1"

의 출력은 LC_COLLATE=en_US.utf8 locale -k LC_COLLATE다음과 같습니다

collate-nrules=4
collate-rulesets=""
collate-symb-hash-sizemb=2039
collate-codeset="UTF-8"

답변1

C로케일이 아닌 다른 것을 사용하는 경우 유사한 범위는 [a-z]로케일에 따라 달라지며 항상 예상한 결과를 제공하지 않으므로 사용하면 안 됩니다. 이미 발생한 대소문자 문제 외에도 일부 로케일에서는 분음 부호를 사용하여 문자를 처리합니다(예:)는 기본 문자(즉,).

대신 명명된 문자 클래스를 사용하세요.

echo B | grep '[[:lower:]]'

그러면 해당 로케일에 대해 항상 올바른 결과가 제공됩니다. 그러나 입력 텍스트와 적용하려는 테스트의 의미를 반영하는 로케일을 선택해야 합니다.

예를 들어 특정 바이트 값을 찾아야 하는 경우 C항상 사용 가능한 로캘을 사용하세요.

echo B | LANG=C grep '[a-z]'

이것이 예상대로 작동하지 않는다면 이는 실제로 버그입니다.

답변2

정규식의 범위는 데이터 정렬 설정을 따라야 합니다. 관련 표준은 다음과 같습니다.http://pubs.opengroup.org/onlinepubs/007908799/xbd/re.html("범위 표현"을 찾으십시오). 따라서 해당 로캘에 따라 합리적인 정의가 출력되어야 echo B | LC_COLLATE=en_US grep '[a-z]'합니다 . B이것이 때때로 작동하지 않는 이유를 설명할 수는 없지만 제대로 설치되고 구성된 비고대 시스템에서 이 문제가 발생하면 매우 놀랄 것입니다.

관련 정보