Perl에서 UTF-8을 어떻게 출력 할 수 있습니까?


110

"utf8"pragma를 사용하여 Perl 스크립트를 작성하려고하는데 예상치 못한 결과가 나타납니다. Mac OS X 10.5 (Leopard)를 사용하고 있으며 TextMate로 편집하고 있습니다. 내 편집기와 운영 체제에 대한 모든 설정은 기본적으로 utf-8 형식으로 파일을 작성하도록되어 있습니다.

그러나 텍스트 파일에 다음을 입력하고 ".pl"로 저장하고 실행하면 ASCII가 아닌 문자 대신 친숙한 "물음표가있는 다이아몬드"가 표시됩니다.

#!/usr/bin/env perl -w

use strict;
use utf8;

my $str = 'Çirçös';
print( "$str\n" );

내가 뭘 잘못하고 있는지 아십니까? 출력에서 'Çirçös'를 기대하지만 대신 ' ir s'를 얻습니다.


1
어쩌면 프로그램이 아닐 수도 있습니다. .. 출력을 수행하는 편집기에 쉘이 있다고 생각합니다
n00ki3

모든 답변은 명시 적으로 UTF8로 설정하는 방법에 대한 질문에 올바르게 대답합니다. stackoverflow.com/a/14405949/498634에 표시된대로 터미널의 로케일 설정을 조정해야한다고 생각합니다 . 터미널이 UTF8로 설정되지 않은 경우 UTF8로 STDOUT에 기록 된 데이터가 잘못 인코딩됩니다 !
Daniel Böhmer

작업 방법에 대한 훌륭한 답변utf8 :
Eugen Konkov

답변:


160

use utf8;유니 코드 출력을 활성화하지 않습니다 . 프로그램에 유니 코드를 입력 할 수 있습니다. 당신의 print()진술 앞에 이것을 프로그램에 추가하십시오 :

binmode(STDOUT, ":utf8");

도움이되는지 확인하십시오. STDOUT일반 ASCII 대신 UTF-8로 출력 해야합니다 .


나는 이것에 대해 몰랐습니다 (나는 UTF8을 데이터베이스에 넣고 인쇄하지 않았습니다). +1.
Paul Tomblin

1
천만에요. 또 다른 정답을 참조하십시오 : stackoverflow.com/questions/627661/writing-perl-code-in-utf8/… 그리고 TMTOWTDI를 기억하십시오. 그리고 @ 폴 - 당신은 파일 방법입니다 쓰기 UTF-8, 당신은 아마 그 파일 핸들에 bin 파일 모드 ()를 사용하고 "적절한"UTF-8 할,하지만 .. 작동하는 경우에하는 경우는
크리스 루츠

1
다른 방법 : open pragma ( search.cpan.org/perldoc/open ), -C 스위치 ( perldoc.perl.org/perlrun.html#-C )
ysth

1
여기에 FWIW가 그 이유입니다. utf8에 다소간 저장되었지만 latin1 (ISO-8859-1) 문자 만 포함 된 문자열은 기본적으로 latin1로 출력됩니다. 이런 식으로 유니 코드 이전 시대의 스크립트는 유니 코드 인식 펄을 사용하더라도 동일하게 작동합니다.
mirod

3
utf8 pragma를 사용하면 소스를 UNICODE로 작성할 수 없으며, 중요한 차이점 인 UNICODE의 UTF-8 (또는 UTF-EBCDIC) 인코딩으로 소스를 이해할 수 있습니다.
Chas. 오웬

83

open pragma를 사용할 수 있습니다 .

예를 들어. 아래는 UTF-8을 사용하도록 STDOUT, STDIN 및 STDERR을 설정합니다 ....

use open qw/:std :utf8/;

1
BTW ... 나는 너에게 +1을 주었다. 이 상황에서는 binmode (STDOUT, ': utf8')가 더 정확하다고 생각합니다. "use open"은 다른 좋은 용도로 사용되지만 STDOUT 만 인코딩하도록 설정하는 방법을 찾을 수없는 것 같습니다.
draegtun

66

TMTOWTDI 는 작업 방식에 가장 적합한 방법을 선택했습니다. 환경 방법을 사용하므로 생각할 필요가 없습니다.

에서 환경 :

export PERL_UNICODE=SDL

상의 명령 행 :

perl -CSDL -le 'print "\x{1815}"';

또는 binmode 사용 :

binmode(STDOUT, ":utf8");          #treat as if it is UTF-8
binmode(STDIN, ":encoding(utf8)"); #actually check if it is UTF-8

또는 PerlIO 사용 :

open my $fh, ">:utf8", $filename
    or die "could not open $filename: $!\n";

open my $fh, "<:encoding(utf-8)", $filename
    or die "could not open $filename: $!\n";

또는 open pragma 사용 :

use open ":encoding(utf8)";
use open IN => ":encoding(utf8)", OUT => ":utf8";

1
포괄적 인 답변을 원하시면 +1; 참고 SDL로 모두 암시 -C하고 PERL_UNICODE. use open ':locale'이의에서 스크립트 등가이기 때문에 pragma는 또한 언급 할만큼 가치있다 -Cexport PER_UNICODE=. 이 3 가지 중 하나는 환경의 로케일이 UTF8 기반이라고 가정하고 모든 입력 및 출력 스트림 (파일 또는 stdin / stdout / stderr)에 대해 UTF8 지원을 제공합니다. 마지막으로 소스 코드를 UTF8로 처리 하려면 use utf8;pragma를 사용하십시오 .
mklement0

perl -Mutf8 -CSDL -e '...'/ 출력 UTF-8 소비 할 수 있습니다 뿐만 아니라 내부로 사용 UTF-8 리터럴 -e가난한 사람의 경우 폴더에 대한 예를 :perl -Mutf8 -CASDL -pe 'y/āáǎàēéěèīíǐìōóǒòūúǔùǖǘǚǜĀÁǍÀĒÉĚÈĪÍǏÌŌÓǑÒŪÚǓÙǕǗǙǛ/aaaaeeeeiiiioooouuuuüüüüAAAAEEEEIIIIOOOOUUUUÜÜÜÜ/'
vladr


0

감사합니다. 마침내 코드 전체에 utf8 :: encode를 넣지 않는 해결책을 찾았습니다. utf8에서 파일 쓰기 및 읽기와 같은 다른 경우를 합성하고 완료하고 utf8에서 YAML 파일의 LoadFile과 함께 작동합니다.

use utf8;
use open ':encoding(utf8)';
binmode(STDOUT, ":utf8");

open(FH, ">test.txt"); 
print FH "something éá";

use YAML qw(LoadFile Dump);
my $PUBS = LoadFile("cache.yaml");
my $f = "2917";
my $ref = $PUBS->{$f};
print "$f \"".$ref->{name}."\" ". $ref->{primary_uri}." ";

여기서 cache.yaml은 다음과 같습니다.

---
2917:
  id: 2917
  name: Semanário
  primary_uri: 2917.xml

-3

쉘에서 수행하십시오 : $ env | grep LANG

이것은 아마도 쉘이 utf-8 로케일을 사용하지 않는다는 것을 보여줄 것입니다.


실제로 utf-8로 설정되었습니다. 문제는 binmode를 utf-8로 설정하지 않고 STDOUT으로 출력하고 있다는 것입니다.

2
이것은 직교 문제입니다. 터미널 에뮬레이터가 데이터를 해석하는 방법에 대해 걱정하기 전에 올바른 데이터를 출력하려면 Perl 스크립트가 필요합니다.
jrockway
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.