읽을 수 있는 문자만 포함된 정규식과 일치하는 읽을 수 없는 문자열

읽을 수 있는 문자만 포함된 정규식과 일치하는 읽을 수 없는 문자열

다음 명령을 고려하십시오.

STR="Êîðîëü è Øóò"; # Invalid (Russian in unrecognized encoding)
#STR="а б в г д"; # Valid (Russian)
#STR="a b c d e"; # Valid (English)
#STR="a b c d e а б в г д"; # Valid (English and Russian)



# The regex consists of latin and Russian characters
REGEX="^[a-zA-Zа-яА-Я ]+$"

if ! [[ "$STR" =~ $REGEX ]] ; then
  echo "Unreadable string: ""$STR";
fi


$ echo $LC_ALL
ru_RU.UTF-8

나는 "Unreadable string: Êîðîëü è Øóò"약간의 결과를 기대했지만 아무것도 얻지 못했습니다.

답변1

POSIX 로케일을 제외하고 POSIX는 A-Z유사 또는 일치의 범위를 지정하지 않습니다(명확하지 않음).а-яA-Zа-я

[A-Z]POSIX 로케일에서만 문자만 일치하도록 보장 됩니다 .ABCDEFGHIJKLMNOPQRSTUVWXYZ

다른 로캘에서는 구현에 따라 동작이 달라집니다. 일부는 전후 A에 정렬된 모든 데이터 정렬 요소(문자 또는 문자 시퀀스일 수 있음)와 일치 할 수 있습니다 Z( ch, x또는 포함할 수 있지만 포함 Á되지 않음 Ź). A로케일의 문자 세트 Z또는 로케일의 대조 데이터를 다르게 사용할 수 있습니다... 또한 모든 사람이 특정 스크립트의 알파벳 순서에 동의하는 것은 아닙니다(예: 이 경우 라틴어 또는 키릴 문자). 문자 세트에 이러한 스크립트를 포함하는 다른 로케일(동일한 문자 세트라도).

스크립트의 알파벳 문자를 일치시키려면 를 사용하고 [[:alpha:]], UTF-8의 코드 포인트를 기반으로 문자 범위를 일치시키려면 C.UTF-8시스템에서 사용 가능한 많은 로케일 중 하나를 사용해 볼 수 있습니다.

라틴어 문자와 일치시키려면 perl또는 pcre' ( , ... \p{Latin}포함 )을 사용할 수 있습니다. 존재하다 :éÊzsh

set -o rematchpcre
[[ $x =~ '^(\p{Latin}|\p{Cyrillic})$' ]]

zsh라틴 문자를 ASCII( still with 및 still with rematchpcre) 에 있는 문자로만 제한할 수 있습니다 .

[[ $x =~ '^((?=[[:ascii:]])\p{Latin}|\p{Cyrillic})$' ]]

에서는 유효하지만 rematchpcrePCRE 및 in의 범위는 코드 포인트 값을 기반으로 하고 문자는 동일한 코드 포인트를 가지며 영어 알파벳 순서임을 보장하므로 ^([a-zA-Z]|\p{Cyrillic})$동일한 효과가 있습니다 . 모든 로케일은 ASCII 기반 및 EBCDIC 기반 POSIX 시스템입니다. zsh적어도.

또는 하위 집합만 원하는 경우 모든 모호함을 피하기 위해 문자를 명시적으로 나열할 수 있습니다.

[[ $x =~ ^[ABC...XYZabc...xyzабв...эюя]$ ]]

언제든지 다음과 같은 변수에 저장할 수 있습니다.

ascii_upper=ABC...XYZ
ascii_lower=abc...xzy
cyr_upper=...
[[ $x =~ ^[$ascii_upper$ascii_lower$cyr_upper...]$ ]]

관련 정보