내 Perl이 유니코드와 잘 작동하지 않는 이유는 무엇입니까?

내 Perl이 유니코드와 잘 작동하지 않는 이유는 무엇입니까?

새로운 Arch 설치에서는 perl유니코드가 제대로 작동하지 않는 것 같습니다. 예를 들어 다음 입력 파일이 있다고 가정해 보겠습니다.

ελα ρε
王小红

이 명령은 각 줄의 마지막 두 문자를 제공해야 합니다.

$ perl -CIO -pe 's/.*(..)$/$1/' file
ε
º¢

그러나 위에서 볼 수 있듯이 나는 횡설수설합니다. 올바른 출력은 다음과 같습니다.

ρε
小红

내 터미널( )이 UTF-8을 지원한다는 것을 알고 있습니다. gnome-terminator둘 다 예상대로 작동하기 때문입니다.

$ cat file
ελα ρε
王小红
$ perl -pe '' file
ελα ρε
王小红

불행히도 없이는 -CIO파일 perl을 올바르게 처리하지 못합니다.

$ perl -pe 's/.*(..)$/$1/' file
ε
��

또한 로케일 문제가 되어서는 안 됩니다.

$ locale
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

일부 Perl 패키지를 설치해야 할 것 같은데 어떤 패키지인지 모르겠습니다. 관련 정보:

$ perl --version | grep subversion
This is perl 5, version 22, subversion 0 (v5.22.0) built for x86_64-linux-thread-multi

$ pacman -Qs unicode
local/fribidi 0.19.7-1
    A Free Implementation of the Unicode Bidirectional Algorithm
local/icu 55.1-1
    International Components for Unicode library
local/libunistring 0.9.6-1
    Library for manipulating Unicode strings and C strings
local/perl 5.22.0-1 (base)
    A highly capable, feature-rich programming language
local/perl-unicode-stringprep 1.105-1
    Preparation of Internationalized Strings (RFC 3454)
local/perl-unicode-utf8simple 1.06-5
    Conversions to/from UTF8 from/to characterse
local/ttf-arphic-uming 0.2.20080216.1-5
    CJK Unicode font Ming style

유니코드와 잘 작동하도록 Perl을 설치하려면 어떻게 해야 합니까?

답변1

설명하신 문제는 제가 테스트한 시스템의 표준 동작입니다. stdin 및 stdout에 영향을 미치 I므로 O다음과 같이 작동합니다.

→ cat data | perl -CIO -pe 's/.*(..)$/$1/'
ρε
小红

반면에 그렇지 않을 수도 있습니다:

→ perl -CIO -pe 's/.*(..)$/$1/' data
ε
º¢

있다두 가지 추가 옵션perl -C원하는 행동을 만들어내는 것입니다.

i     8   UTF-8 is the default PerlIO layer for input streams
o    16   UTF-8 is the default PerlIO layer for output streams

이는 기본적으로 Perl에게 파일 열기 형식을 사용하라는 의미입니다.

open(F, "<:utf8", "data");

perl -CSD또는 약어를 사용할 수 있습니다perl -CIOEio

S     7   I + O + E
D    24   i + o

그러면 당신은 얻습니다

→ perl -CSD -pe 's/.*(..)$/$1/' data
ρε
小红

환경 PERLIO변수가 설정되고 포함되면 :utf8이 동작도 활성화됩니다.

perl기본 동작은 구성/컴파일 시에도 수정할 수 없는 것 같습니다 (아래 cuonglm 설명 참조). 아치는 확실히 그렇지 않습니다무엇이든 설정하세요.나는 데비안 펄 패키지가 기본 동작을 수정할지 의심스럽습니다.

답변2

그건 시스템의 문제가 아니라 그 perl자체의 문제입니다.

-CIOUTF-8 인코딩은 STDIN미리 정의된 파일 핸들 STDOUT3개 중 2개 ( for 에도 perl있음 )에만 설정하세요.-ESTDERR

당신이 사용할 때:

perl -CIO -pe 's/.*(..)$/$1/' file

perl파일 처리를 위해 다이아몬드 연산자를 사용합니다 <>. 다이아몬드 연산자를 <>사용한 이후개방형(두 개의 인수 형식 사용)STDIN명령줄에서 각 파일에 대해 새 파일 핸들을 만들려면 이러한 파일 핸들은 및 에 설정한 UTF-8 인코딩의 영향을 받지 않습니다 STDOUT.

따라서 파일의 내용을 perlstdin을 통해 전달할 수 있으며 다음과 같이 작동합니다.

perl -CIO -pe 's/.*(..)$/$1/' <file

다른 옵션은 다음을 참조하세요.@맷의 답변.


perl기본 인코딩 레이어에 로케일을 사용 하려는 경우 다음을 사용할 수 있습니다.

perl -Mopen=:locale -pe 's/.*(..)$/$1/' file

PERLIO인코딩 레이어 설정에 사용할 때 다음을 수행해야 합니다.:encoding(uf8)대신에 사용:utf8.

:utf8인코딩 단계를 건너 뛰면 잘못된 UTF-8 바이트 시퀀스를 읽을 때 문제가 발생하여 보안 문제가 발생할 수 있습니다.

관련 정보