2009-10-23 15 views
7

मैं पहले से ही कैसे UTF-8 एनकोड करने के लिए लाइन द्वारा एक फ़ाइल लाइन के गैर UTF8 एन्कोड सामग्री परिवर्तित करने के लिए, निम्न कोड की तरह कुछ का उपयोग कर पता:मैं पर्ल में एक इनपुट फ़ाइल को यूटीएफ -8 एन्कोडिंग में कैसे परिवर्तित कर सकता हूं?

# outfile.txt is in GB-2312 encode  
open my $filter,"<",'c:/outfile.txt'; 

while(<$filter>){ 
#convert each line of outfile.txt to UTF-8 encoding 
    $_ = Encode::decode("gb2312", $_); 
...} 

लेकिन मुझे लगता है पर्ल सीधे पूरे सांकेतिक शब्दों में बदलना कर सकते हैं UTF-8 प्रारूप करने के लिए इनपुट फ़ाइल, कुछ की तरह

#outfile.txt is in GB-2312 encode 
open my $filter,"<:utf8",'c:/outfile.txt'; 

(पर्ल कहते हैं, "UTF8" \ xD4 "यूनिकोड को मैप नहीं है" की तरह कुछ)

और

तो मैं कोशिश की है
open my $filter,"<",'c:/outfile.txt'; 
$filter = Encode::decode("gb2312", $filter); 

वे काम नहीं करते (पर्ल "ReadLine() बंद filehandle पर! कहते हैं)। लेकिन इनपुट फ़ाइल को यूटीएफ -8 एन्कोड में सीधे रूपांतरित करने का कोई तरीका है?

अद्यतन:

ऐसा लगता है कि चीजों के रूप में सरल रूप में मैंने सोचा था कि नहीं कर रहे हैं। अब मैं इनपुट फ़ाइल को यूटीएफ -8 कोड में चौराहे के रास्ते में परिवर्तित कर सकता हूं। मैं पहले इनपुट फ़ाइल खोलता हूं और फिर इसकी सामग्री को यूटीएफ -8 पर एन्कोड करता हूं और फिर आउटपुट को एक नई फाइल में खोलता हूं और फिर आगे की प्रक्रिया के लिए नई फाइल खोलता हूं। इस कोड है:

open my $filter,'<:encoding(gb2312)','c:/outfile.txt'; 
open my $filter_new, '+>:utf8', 'c:/outfile_new.txt'; 
print $filter_new $_ while <$filter>; 
while (<$filter_new>){ 
... 
} 

लेकिन यह बहुत ज्यादा काम है और यह और भी अधिक परेशानी है की तुलना में बस लाइन द्वारा $ फिल्टर लाइन की सामग्री सांकेतिक शब्दों में बदलना।

+3

जब भी आप किसी प्रश्न में चेतावनी संदेश का जिक्र करते हैं, तो प्रश्न में चेतावनी संदेश शामिल करें। :) –

+0

@brian, सुझाव के लिए धन्यवाद। – Mike

+1

सटीक चेतावनी संदेश का उपयोग करना सबसे अच्छा है :) तो, उस चेतावनी के साथ, आपको अपने खुले परिणाम का परिणाम देखना होगा (जिसे आपको हमेशा वैसे भी करना चाहिए)। –

उत्तर

5

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

जब आप इसे वापस लिखते हैं, तो आप जो भी एन्कोडिंग इसे सहेजना चाहते हैं उसका उपयोग करें। हालांकि, आपको इसका उपयोग करने के लिए इसे फ़ाइल में वापस रखना नहीं है।


वर्ष जवाब

पर्ल आई/ओ परतों केवल यह सोचते हैं यह पहले से ही ठीक से एन्कोड किया डेटा पढ़ें। यह आपके लिए एन्कोडिंग कन्वर्ट नहीं करेगा। Utf8 का उपयोग करने के लिए खुला कहकर, आप यह कह रहे हैं कि यह पहले से ही utf8 है।

आपको दिखाए गए अनुसार Encode मॉड्यूल का उपयोग करना होगा (जब तक कि आप अपनी खुद की I/O परत नहीं लिखना चाहते)। आप बाइट्स को यूटीएफ -8 में परिवर्तित कर सकते हैं, या यदि आप एन्कोडिंग जानते हैं, तो आप एक एन्कोडिंग से दूसरे में कनवर्ट कर सकते हैं। चूंकि ऐसा लगता है कि आप पहले ही एन्कोडिंग जानते हैं, तो आप from_to() फ़ंक्शन चाहते हैं।

यदि आप बस पर्ल और यूनिकोड के साथ शुरुआत कर रहे हैं, तो कुछ भी करने से पहले Juerd's Perl Unicode Advice पर जाएं।

+0

@brian, मार्गदर्शन के लिए धन्यवाद। मैंने सोचा कि इसे खोलने के दौरान इनपुट फ़ाइल को यूटीएफ -8 एन्कोड में सीधे रूपांतरित करने का कुछ आसान तरीका होना चाहिए। लेकिन अब ऐसा लगता है कि चीजें इतनी सरल नहीं हैं। मैं सोच रहा हूं कि मैं पहले इनपुट फ़ाइल खोल सकता हूं और फिर सामग्री को यूटीएफ -8 में एन्कोड कर सकता हूं और फिर यूटीएफ -8 एन्कोड में दूसरी फ़ाइल में आउटपुट कर सकता हूं और फिर उस दूसरी फ़ाइल को खोल सकता हूं। कोड इस तरह दिखता है: मेरा $ फ़िल्टर खोलें, '<: एन्कोडिंग (gb2312)', 'c: /outfile.txt'; मेरा $ filter_new खोलें, '+>: utf8', 'c: /f2.txt'; प्रिंट $ filter_new $ _ जबकि <$filter>; जबकि (<$filter_new>) {...} लेकिन यह बहुत अधिक काम है। जबकि (<$fh_out>) { – Mike

+0

बहुत अधिक काम का आपका विचार skewed है। इसे हाथ से करने का प्रयास करें और फिर वापस आएं और हमें बताएं कि पर्ल इसे आपके लिए कितना आसान बनाता है। बच्चों को आज नहीं पता कि उनके पास कितना अच्छा है। :) –

+0

माइक की सहजताएं सही हैं; आप सीधे इच्छित रूपांतरण करने के लिए परतों को ढेर कर सकते हैं :) – ysth

4

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

लेकिन यदि आप डेटा के साथ कुछ कर रहे हैं, जहां perl इसे utf8 से डाउनग्रेड करने का प्रयास करेगा, तो आपको या तो पर्ल को बताने के लिए बिनमोड (STDOUT, ": utf8") करने के लिए नहीं करना चाहिए (उदाहरण के लिए, stdout के लिए आउटपुट utf8 होना चाहिए), या आपको अपने यूटीएफ 8 को द्विआधारी डेटा के रूप में समझना होगा (प्रत्येक बाइट को अलग से व्याख्या करना, और utf8 अक्षरों के बारे में कुछ भी नहीं जानना।)

ऐसा करने के लिए, आपको बस एक आवेदन करना है अपने खुले करने के लिए अतिरिक्त परत:

open my $foo, "<:encoding(gb2312):bytes", ...; 

ध्यान दें कि निम्नलिखित के उत्पादन में ही होगा:

perl -we'open my $foo, "<:encoding(gb2312):bytes", "foo"; $bar = <$foo>; print $bar' 
perl -CO -we'open my $foo, "<:encoding(gb2312)", "foo"; $bar = <$foo>; print $bar' 

लेकिन एक मामले में, पर्ल जानता है कि डेटा को पढ़ने UTF8 (और इसलिए लंबाई ($ बार) UTF8 वर्णों की संख्या रिपोर्ट करेंगे) और (-CO द्वारा) स्पष्ट रूप से बताया जाना है कि STDOUT UTF8 स्वीकार करेंगे , और दूसरे में, perl डेटा के बारे में कोई धारणा नहीं करता है (और इसलिए लंबाई ($ बार) बाइट्स की संख्या की रिपोर्ट करेगा), और बस इसे प्रिंट करता है।

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