2010-06-03 18 views
8

पर्ल स्ट्रिंग आंतरिक रूप से कैसे प्रदर्शित होते हैं? क्या एन्कोडिंग का उपयोग किया जाता है? मैं अलग-अलग एन्कोडिंग को सही तरीके से कैसे संभालूं?पर्ल स्ट्रिंग्स आंतरिक

मैं काफी लंबे समय तक पेर्ल का उपयोग कर रहा हूं, लेकिन इसमें विभिन्न एन्कोडिंग में बहुत सी स्ट्रिंग हैंडलिंग शामिल नहीं थी, और जब मुझे एक मामूली समस्या का सामना करना पड़ा जिसमें एन्कोडिंग के साथ कुछ करना था, तो मैं आमतौर पर कुछ का सहारा लेता था शैमिक क्रियाएं

इस पल तक मैंने बाइट्स के अनुक्रमों के रूप में पर्ल स्ट्रिंग्स के बारे में सोचा, जो मेरे कार्यों के लिए बहुत अच्छी तरह फिट हुआ। अब मुझे यूटीएफ -8 एन्कोडेड फ़ाइल की कुछ प्रसंस्करण करने की आवश्यकता है और यहां परेशानी शुरू होती है।

पहले, मैं फ़ाइल स्ट्रिंग में इस तरह पढ़ें:

open(my $in, '<', $ARGV[0]) or die "cannot open file $ARGV[0] for reading"; 
binmode($in, ':utf8'); 

my $contents; 

{ 
    local $/; 
    $contents = <$in>; 
} 

close($in); 

तो बस इसे प्रिंट:

print $contents; 

और मैं दो बातें मिलती है: एक चेतावनी Wide character in print at <scriptname> line <n> और कंसोल में एक कचरा। तो मैं निष्कर्ष निकाल सकता हूं कि पर्ल स्ट्रिंग्स में "चरित्र" की एक अवधारणा है जो "चौड़ी" हो सकती है या नहीं, लेकिन जब इन "चौड़े" वर्णों को मुद्रित किया जाता है तो कंसोल में एकाधिक बाइट्स के रूप में प्रतिनिधित्व किया जाता है, न कि एकल "चरित्र" के रूप में। (मुझे आश्चर्य है कि बाइनरी फाइलों के साथ मेरे पिछले पिछले अनुभव ने काफी काम क्यों किया है, मुझे उम्मीद है कि यह किसी भी "चरित्र" मुद्दों के बिना काम करने की उम्मीद है)।

फिर मुझे कंसोल में कचरा क्यों दिखाई देता है? यदि पर्ल कुछ ज्ञात एन्कोडिंग में चरित्र के रूप में तारों को स्टोर करता है, तो मुझे नहीं लगता कि कंसोल एन्कोडिंग और प्रिंट टेक्स्ट को सही तरीके से ढूंढने में बड़ी समस्या है। (मैं विंडोज, बीटीडब्ल्यू का उपयोग करता हूं)।

यदि पर्ल चर-चौड़ाई वाले वर्ण अनुक्रमों के रूप में तारों को स्टोर करता है (उदा। उसी यूटीएफ -8 एन्कोडिंग का उपयोग करके), ऐसा क्यों किया जाता है? मेरे सी अनुभव से हैंडलिंग स्ट्रिंग दर्द है।

अद्यतन

मैं परीक्षण के लिए दो कंप्यूटरों का उपयोग करता हूं, एक अंग्रेजी भाषा पैक के साथ विंडोज 7 x64 चलाता है, लेकिन सक्रिय क्षेत्रीय सेटिंग्स के साथ रूसी क्षेत्रीय सेटिंग्स (इसलिए मेरे पास OEM कोडपेज और सीपी 1251 एएनएसआई के रूप में cp866 है) ActivePerl 5.10.1 x64 के साथ; दूसरा सिग्विन पर्ल 5.10.0 के साथ विंडोज एक्सपी 32 बिट रूसी स्थानीयकरण चलाता है।

लिंक के लिए धन्यवाद, अब मुझे क्या हो रहा है और चीजों को कैसे किया जाना चाहिए, इस बारे में और अधिक ठोस समझ है।

उत्तर

4

फ़ाइल से पढ़ने से पहले utf8 सेट करना अच्छा है, यह स्वचालित रूप से बाइट को आंतरिक एन्कोडिंग में डीकोड करता है। (जो यूटीएफ -8 भी है लेकिन आपको जानने की जरूरत नहीं है, और भरोसा नहीं करना चाहिए।)

प्रिंटिंग से पहले आपको अक्षरों को बाइट्स पर एन्कोड करने की आवश्यकता है।

use Encode; 
utf8::encode($contents); 

यूनिकोड की तुलना में अन्य एन्कोडिंग के लिए, एनकोड के दो तर्क रूप भी हैं। (वह वाक्य बहुत ज्यादा गूंजता है, है ना?)

यहां एक अच्छा संदर्भ है। (और अधिक होता, लेकिन यह मेरी पहली पोस्ट है।) पेर्लुनिटट भी देखें, और सॉफ्टवेयर पर जोएल पर यूनिकोड आलेख।

http://www.ahinea.com/en/tech/perl-unicode-struggle.html

ओह, और यह, मल्टी-बाइट तार का उपयोग करना चाहिए क्योंकि अन्यथा यह सिर्फ यूनिकोड नहीं है।

+0

बहु-बाइट तारों से मेरा मतलब चर-चौड़ाई एन्कोडिंग था। – n0rd

+0

वैसे भी मुझे नहीं मिलता कि मुझे स्पष्ट रूप से रूपांतरण क्यों करना है: मैंने इनपुट डेटा एन्कोडिंग निर्दिष्ट क्यों मुझे कुछ अतिरिक्त कदम उठाने हैं? – n0rd

+2

आपने इनपुट एन्कोडिंग निर्दिष्ट की है। आप अपनी चीजें करते हैं फिर आप अपना आउटपुट एन्कोडिंग निर्दिष्ट करते हैं। जिन लेखों को मैं संदर्भित करता हूं उन्हें बेहतर समझाता है, मुझे सोचना चाहिए। – dylan

2

आपको अपने वास्तविक विंडोज और पर्ल संस्करणों का जिक्र करना चाहिए क्योंकि यह वास्तव में आपके उपयोग किए गए संस्करणों और स्थापित भाषा संकुलों पर निर्भर करता है।

पर्ल तार्किक चौड़ा वर्णों का उपयोग करता आंतरिक रूप से तार का प्रतिनिधित्व करने के लिए -
अन्यथा PerlUnicode पहले मैनुअल पर एक नजर है।

यह आपके बयान की पुष्टि करेगा।

विंडोज सभी यूटीएफ 8 चरित्र को पूरी तरह से स्थापित नहीं करता है - इस प्रकार यह आपके मुद्दे का कारण हो सकता है। आपको एक अतिरिक्त भाषा पैकेज स्थापित करने की आवश्यकता हो सकती है।

+0

आपकी अंतिम वाक्य बिल्कुल समझ में नहीं आता है। आप फोंट का उल्लेख करते हैं, लेकिन इसका एन्कोडिंग के साथ कुछ लेना देना नहीं है। – daxim

4

पर्ल स्ट्रिंग्स को दो एन्कोडिंग में से एक में आंतरिक रूप से संग्रहीत किया जाता है, या तो 8-बिट बाइट उन्मुख देशी एन्कोडिंग, या यूटीएफ -8। पिछली तुलनात्मकता के लिए धारणा यह है कि सभी I/O और तार देशी एन्कोडिंग में हैं, जब तक अन्यथा निर्दिष्ट नहीं किया जाता है। मूल एन्कोडिंग आमतौर पर 8-बिट ASCII है, लेकिन इसे use locale के साथ बदला जा सकता है।

अपने नमूने में आप :utf8 अर्थशास्त्र का उपयोग करने के लिए इसे अपने इनपुट हैंडल पर बिनमोड कहते हैं। इसका एक प्रभाव यह है कि इस हैंडल से पढ़ने वाले सभी तारों को यूटीएफ -8 के रूप में एन्कोड किया जाएगा। print डिफ़ॉल्ट रूप से STDOUT पर लिखता है, और STDOUT देशी एन्कोडेड वर्णों की अपेक्षा करने के लिए डिफ़ॉल्ट रूप से लिखता है।

सही चीज करने के प्रयास में पर्ल एक यूटीएफ -8 स्ट्रिंग को देशी एन्कोडेड आउटपुट पर भेजने की अनुमति देगा, लेकिन अगर उस हैंडल से कोई एन्कोडिंग संलग्न नहीं है तो उसे अनुमान लगाया जाना चाहिए कि बहु-बाइट कैसे आउटपुट करना है पात्रों और यह लगभग निश्चित रूप से गलत अनुमान लगाएगा। चेतावनी का मतलब यही है, एक बहु-बाइट चरित्र केवल एक बाइट वर्णों की अपेक्षा करते हुए एक धारा में भेजा गया था और नतीजा यह था कि चरित्र शायद अनुवाद में क्षतिग्रस्त हो गया था।

आप क्या हासिल करना आप एक एकल बाइट कैरेक्टर सेट है कि सुरक्षित रूप से मुद्रित किया जा सकता है या करने के लिए UTF-8 डेटा कन्वर्ट करने के लिए एनकोड मॉड्यूल डायलन ने उल्लेख उपयोग कर सकते हैं चाहते हैं पर निर्भर करता है

आप जानते हैं कि जो कुछ भी STDOUT से जुड़ा हुआ है संभाल कर सकते हैं यूटीएफ -8 आप यूआरएफ -8 के रूप में भेजे जाने के लिए STDOUT पर भेजे गए किसी भी डेटा को पर्ल को बताने के लिए binmode(STDOUT, ':utf8'); का उपयोग कर सकते हैं।

+0

यदि डिफॉल्ट एन्कोडिंग 8 बिट ASCII (या कोई अन्य 8 बिट एन्कोडिंग) था, तो क्यों पर्ल यूटीएफ -8 तारों को कच्चे बाइट्स के रूप में मुद्रित करता है (यानी ट्रांसकोडिंग के परिणाम प्रिंट करने के बजाय मुद्रित स्ट्रिंग में प्रत्येक सिरीलिक वर्ण के लिए दो अक्षर प्रिंट करना) वह एन्कोडिंग जिसमें मूल स्ट्रिंग के समान वर्णों की एक ही मात्रा होगी? – n0rd

+1

@ n0rd एक यूटीएफ -8 स्ट्रिंग पर्ल परिप्रेक्ष्य से बाइट नहीं है, यह वर्ण हैं। इस आईआईआरसी का एक अजीब परिणाम यह है कि जब एन्कोडिंग के बिना एक हैंडल पर मुद्रित किया जाता है तो यह 255 से अधिक यूनिकोड कोड पॉइंट को केवल 8-बिट्स तक छोटा कर देगा। –

संबंधित मुद्दे