정돈하다order through는 LC_COLLATE
개별 문자의 정렬 순서를 정의할 뿐만 아니라 문자 범위의 의미도 정의합니다. 아니면 그럴까요? 다음 스니펫을 고려하세요.
unset LANGUAGE LC_ALL
echo B | LC_COLLATE=en_US grep '[a-z]'
직관적으로 B
is is not in [a-z]
이므로 아무 것도 출력해서는 안 됩니다. 이것이 Ubuntu 8.04 또는 10.04에서 발생하는 현상입니다. 그러나 데비안 lenny 또는 squeeze를 실행하는 일부 컴퓨터에서는 범위에 대문자를 포함하여 B
데이터 정렬 안과 사이의 a-z
모든 항목이 포함된다는 것을 알 수 있습니다.a
z
B
Z
테스트된 모든 시스템에는 en_US
로케일이 생성되었습니다. 나는 또한 로케일을 변경해 보았습니다. B
위의 일치하는 기계 에서 이것은 {en_{AU,CA,GB,IE,US},fr_FR,it_IT,es_ES,de_DE}{iso8859-1,iso8859-15,utf-8}
일본어(사용 가능한 인코딩) 및 /를 제외하고 .C
POSIX
정규식에서 문자 범위는 무엇을 의미합니까?, 언제 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
이것이 때때로 작동하지 않는 이유를 설명할 수는 없지만 제대로 설치되고 구성된 비고대 시스템에서 이 문제가 발생하면 매우 놀랄 것입니다.