मैं पर्ल से UTF-8 का उत्पादन कैसे कर सकता हूं?


110

मैं "utf8" pragma का उपयोग करके एक पर्ल स्क्रिप्ट लिखने की कोशिश कर रहा हूं, और मुझे अप्रत्याशित परिणाम मिल रहे हैं। मैं Mac OS X 10.5 (तेंदुआ) का उपयोग कर रहा हूं, और मैं TextMate के साथ संपादन कर रहा हूं। मेरे संपादक और ऑपरेटिंग सिस्टम दोनों के लिए मेरी सभी सेटिंग्स utf-8 प्रारूप में फाइलें लिखने के लिए डिफ़ॉल्ट हैं।

हालाँकि, जब मैं एक पाठ फ़ाइल में निम्नलिखित दर्ज करता हूं, तो इसे ".pl" के रूप में सहेजें, और इसे निष्पादित करें, मुझे गैर-एएससीआईआई पात्रों के स्थान पर "प्रश्न चिह्न वाला हीरा" मिल जाता है।

#!/usr/bin/env perl -w

use strict;
use utf8;

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

किसी भी विचार मैं गलत क्या कर रहा हूँ? मैं आउटपुट में 'çirçös' प्राप्त करने की उम्मीद करता हूं, लेकिन मुझे इसके बजाय 'getir s' मिलते हैं।


1
शायद यह कार्यक्रम नहीं है .. मुझे लगता है कि इसका शेल आपके संपादक को आउटपुट देता है
n00ki3

सभी उत्तर आपके प्रश्न का सही उत्तर देते हैं कि इसे स्पष्ट रूप से UTF8 में कैसे सेट करें। मुझे लगता है कि आपको अपने टर्मिनल की लोकेल सेटिंग में समायोजित होना चाहिए जैसा कि stackoverflow.com/a/14405949/498634 में दिखाया गया है । टर्मिनल को UTF8 पर सेट नहीं किया जा सकता है और फिर UTF8 में STDOUT को लिखे गए डेटा को गलत तरीके से एनकोड किया जाएगा !
डैनियल बोहमर

महान जवाब कैसे साथ काम करने के लिए utf8:
यूजेन कोनकोव

जवाबों:


160

use utf8;यूनिकोड आउटपुट को सक्षम नहीं करता है - यह आपको अपने प्रोग्राम में यूनिकोड टाइप करने में सक्षम बनाता है। अपने print()बयान से पहले कार्यक्रम में इसे जोड़ें :

binmode(STDOUT, ":utf8");

देखें कि क्या मदद मिलती है। यह STDOUTसामान्य ASCII के बजाय UTF-8 में आउटपुट बनाना चाहिए ।


मुझे इस बारे में पता नहीं था (मैं केवल एक डेटाबेस में UTF8 डाल रहा हूं, इसे कभी नहीं प्रिंट करता हूं)। +1।
पॉल टॉम्बलिन

1
आपका स्वागत है। एक अन्य सही उत्तर भी देखें: stackoverflow.com/questions/627661/writing-perl-code-in-utf8/… और याद रखें, TMTOWTDI। और @Paul - यदि आप किसी फ़ाइल में UTF-8 लिख रहे हैं, तो आपको संभवतः उस फ़ाइलहैंड पर Binmode () का उपयोग करना चाहिए और इसे "उचित" UTF-8 बनाना चाहिए, लेकिन यदि यह काम करता है ..
क्रिस लुत्ज़

1
अन्य तरीके: खुला प्राग्मा ( search.cpan.org/perldoc/open ), -C स्विच ( perldoc.perl.org/perlrun.html#-C )
ysth

1
एफडब्ल्यूआईडब्ल्यू यहां कारण है: तार जिसमें केवल लैटिन 1 (आईएसओ-8859-1) अक्षर हैं, utf8 में अधिक या कम संग्रहीत होने के बावजूद, डिफ़ॉल्ट रूप से लैटिन 1 के रूप में आउटपुट होगा। इस तरह से एक पूर्व-यूनिकोड युग से स्क्रिप्ट अभी भी एक ही काम करती है, यहां तक ​​कि एक यूनिकोड-जागरूक पर्ल के साथ भी।
mirod

3
Utf8 pragma आपको UNICODE में अपना स्रोत लिखने नहीं देता है, यह आपके स्रोत को UNICODE के UTF-8 (या UTF-EBCDIC) एन्कोडिंग में एक महत्वपूर्ण अंतर समझने पर मजबूर करता है।
चास।

83

आप खुले प्रागंम का उपयोग कर सकते हैं ।

उदाहरण के लिए। नीचे सेट STDOUT, STDIN और STDERR UTF-8 का उपयोग करने के लिए ...।

use open qw/:std :utf8/;

1
BTW ... मैंने u +1 दिया। मुझे लगता है कि बिनमोड (STDOUT, ': utf8') शायद इस स्थिति में अधिक सही है। "ओपन का उपयोग करें" के अन्य अच्छे उपयोग हैं, लेकिन मुझे यह पता नहीं लग सकता है कि यू इसे केवल एसटीडी के बारे में बताने के लिए कैसे सेट कर सकता है?
draegtun

66

TMTOWTDI , ने वह तरीका चुना जो आपके काम करने के लिए सबसे उपयुक्त है। मैं पर्यावरण विधि का उपयोग करता हूं इसलिए मुझे इसके बारे में सोचने की जरूरत नहीं है।

में पर्यावरण :

export PERL_UNICODE=SDL

पर कमांड लाइन :

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

या बिनमोड के साथ :

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

या पर्लियो के साथ :

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";

या खुले चश्मे के साथ :

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

1
व्यापक उत्तर के लिए +1; ध्यान दें कि SDLदोनों के साथ निहित है -Cऔर PERL_UNICODEuse open ':locale'Pragma भी लायक उल्लेख कर रहा है, क्योंकि यह के बराबर में स्क्रिप्ट है -Cऔर export PER_UNICODE=। इन 3 में से कोई भी आपको सभी इनपुट और आउटपुट स्ट्रीम के लिए UTF8 सपोर्ट देगा (चाहे फाइलें हो या स्टड / stdout / stderr), यह मानकर कि आपके वातावरण का लोकेशन UTF8- आधारित है। अंत में, स्रोत कोड को UTF8 के रूप में मानने के लिए, use utf8;प्राग का उपयोग करें ।
mklement0

perl -Mutf8 -CSDL -e '...'उपभोग / आउटपुट UTF-8 के साथ- साथ UTF-8 शाब्दिक का उपयोग करने की अनुमति देता है -eउदाहरण के लिए एक गरीब आदमी के मामले फ़ोल्डर के लिए:perl -Mutf8 -CASDL -pe 'y/āáǎàēéěèīíǐìōóǒòūúǔùǖǘǚǜĀÁǍÀĒÉĚÈĪÍǏÌŌÓǑÒŪÚǓÙǕǗǙǛ/aaaaeeeeiiiioooouuuuüüüüAAAAEEEEIIIIOOOOUUUUÜÜÜÜ/'
vladr


0

धन्यवाद, अंत में utf8 नहीं डालने का एक समाधान मिला :: सभी कोड को सांकेतिक शब्दों में बदलना। अन्य मामलों के लिए संश्लेषित और पूरा करने के लिए, जैसे कि 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 लोकेल का उपयोग नहीं कर रहा है।


दरअसल, इसे यूएफ -8 में सेट किया गया था। समस्या यह थी कि मैं utm-8 को बिनमोड की स्थापना के बिना STDOUT में आउटपुट कर रहा था;

2
यह एक ओर्थोगोनल चिंता होगी। अपने टर्मिनल एमुलेटर की व्याख्या कैसे करें, इसके बारे में चिंता करने से पहले आपको सही डेटा आउटपुट के लिए अपनी पर्ल स्क्रिप्ट की आवश्यकता होती है।
मारक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.