내 Perl이 유니코드를 잘 처리하지 못하는 이유는 무엇입니까?

내 Perl이 유니코드를 잘 처리하지 못하는 이유는 무엇입니까?

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

ελα ρε
王小红

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

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

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

ρε
小红

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

$ 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시스템 자체의 문제입니다.

-CIOSTDINSTDOUT사전 정의된 세 개의 파일 핸들 중 두 개인 및 에만 UTF-8 인코딩을 설정합니다 perl( for 에도 있음 -E).STDERR

당신이 사용할 때:

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

perl파일을 처리하려면 다이아몬드 연산자를 사용하세요 <>. 언제부터 <>다이아몬드 카운터를 사용하기 시작했나요?open(두 개의 매개변수 형식을 가짐)명령줄에서 각 파일에 대한 새 파일 핸들을 만들려면 이러한 파일 핸들은 STDIN및 에 설정한 UTF-8 인코딩 의 영향을 받지 않습니다 STDOUT.

따라서 표준 입력을 통해 파일의 내용을 전달하면 perl작동합니다.

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

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


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

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

PERLIO인코딩 레이어를 설정 하는 데 사용할 때는 다음과 같이 해야 합니다.:encoding(uf8)대신 사용:utf8.

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

관련 정보