2010-09-04 8 views
11

में एक यूटीएफ 8 स्ट्रिंग को ASCII में कनवर्ट करें मैंने एनकोड का उपयोग करके Google और StackOverflow की सिफारिश की है (जो मुझे मिल सकती है) की कोशिश की है। मेरा कोड काम करता है लेकिन यह सिर्फ यूटीएफ 8 का उपयोग करता है और मुझे व्यापक चरित्र चेतावनियां मिलती हैं। मुझे पता है कि उन चेतावनियों के आसपास कैसे काम करना है, लेकिन मैं किसी और चीज के लिए यूटीएफ 8 का उपयोग नहीं कर रहा हूं इसलिए मैं इसे केवल कन्वर्ट करना चाहता हूं और इसके साथ निपटने के लिए अपने शेष कोड को अनुकूलित नहीं करना चाहता हूं। यहां मेरा कोड है:पर्ल

my $xml = XMLin($content); 
# Populate the @titles array with each item title. 
my @titles; 
for my $item (@{$xml->{channel}->{item}}) { 
    my $title = Encode::decode_utf8($item->{title}); 
    #my $title = $item->{title}; 
    #utf8::downgrade($title, 1); 
    Encode::from_to($title, 'utf8', 'iso-8859-1'); 
    push @titles, $title; 
} 
return @titles; 

टिप्पणी की गई कि आप कुछ अन्य चीजों को देख सकते हैं जो मैंने कोशिश की है। मुझे अच्छी तरह से पता है कि मुझे नहीं पता कि मैं यहाँ क्या कर रहा हूं। मैं बस एक सादे पुराने ASCII स्ट्रिंग के साथ खत्म करना चाहता हूँ। किसी भी विचार की बहुत प्रशंसा की जाएगी। धन्यवाद।

उत्तर

18

उत्तर इस बात पर निर्भर करता है कि आप शीर्षक का उपयोग कैसे करना चाहते हैं। जाने के 3 बुनियादी तरीके हैं:

  • बाइट्स जो यूटीएफ -8 एन्कोडेड स्ट्रिंग का प्रतिनिधित्व करते हैं।

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

  • यूनिकोड वर्णों की एक स्ट्रिंग।

वर्णों की अवधारणा पर्ल के लिए आंतरिक है। जब आप Encode::decode_utf8 निष्पादित करते हैं, तो पर्ल द्वारा देखे गए बाइट्स का एक गुच्छा वर्णों की एक स्ट्रिंग में परिवर्तित करने का प्रयास किया जाता है। पर्ल वीएम (और प्रोग्रामर लेखन पर्ल कोड) इनपुट पर यूटीएफ -8 बाइट्स को डीकोड करने और आउटपुट पर यूटीएफ -8 बाइट्स को एन्कोड करने के अलावा उस अवधारणा को बाहरी नहीं कर सकता है। उदाहरण के लिए, आपके प्रोग्राम को इनपुट के रूप में दो बाइट प्राप्त होते हैं जिन्हें आप जानते हैं कि वे यूटीएफ -8 एन्कोडेड वर्ण (ओं) का प्रतिनिधित्व करते हैं, मान लें कि 0xC3 0xB6। उस स्थिति में decode_utf8 एक प्रतिनिधित्व देता है कि दो बाइट्स के बजाय, एक वर्ण देखता है: ö

फिर आप पर्ल में उस स्ट्रिंग में हेरफेर करने के लिए आगे बढ़ सकते हैं। आगे अंतर दर्शाने के लिए, निम्नलिखित कोड पर विचार करें:

my $bytes = "\xC3\xB6"; 
say length($bytes); # prints "2" 
my $string = decode_utf8($bytes); 
say length($string); # prints "1" 
  • ASCII के विशेष मामले, UTF-8 के एक सबसेट।

    एएससीआईआई यूनिकोड का एक बहुत छोटा सबसेट है, जहां उस श्रेणी के पात्रों को एक बाइट द्वारा दर्शाया जाता है। यूनिकोड को एएससीआईआई में कनवर्ट करना एक स्वाभाविक रूप से हानिकारक ऑपरेशन है, क्योंकि अधिकांश यूनिकोड वर्ण ASCII वर्ण नहीं हैं। आपको या तो अपनी स्ट्रिंग में हर चरित्र को छोड़ने के लिए मजबूर होना पड़ता है जो कि एएससीआईआई में नहीं है या यूनिकोड को मजबूर करने की कोशिश करते समय यूनिकोड चरित्र से अपने निकटतम ASCII समकक्षों (जो कि अधिकांश मामलों में संभव नहीं है) में मैप करने का प्रयास करता है। ASCII के लिए स्ट्रिंग।

जब से तुम विस्तृत चरित्र चेतावनी है, इसका मतलब है कि आपको लगता है कि ASCII या ISO-8859-1 के रूप में प्रतिनिधित्व नहीं किया जा सकता है (संभवतः उत्पादन) यूनिकोड वर्ण हेरफेर करने के लिए कोशिश कर रहे हैं।

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

आगे पढ़ने के लिए, perldoc का इस्तेमाल करें अध्ययन करने के लिए perlunitut, perlunifaq, perlunicode, perluniintro, और Encode

+1

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

+2

यदि आपको यूटीएफ -8 को ASCII में परिवर्तित करना है, तो आप [टेक्स्ट :: यूनिडकोड] (http://search.cpan.org/perldoc?Text::Unidecode) चाहते हैं। – cjm

+0

@cjm बिल्कुल मुझे क्या चाहिए। यह utf8 अक्षरों को निकटतम दृश्य ASCII विकल्प में परिवर्तित करता है। बहुत धन्यवाद! –

2

आप चेतावनी से छुटकारा पाने के लिए निम्न पंक्ति का उपयोग कर सकते हैं। यह मानता है कि आप यूटीएफ 8 का उपयोग करना चाहते हैं, जो आमतौर पर एक समस्या नहीं होनी चाहिए।

binmode(STDOUT, ":encoding(utf8)");

+1

आपको कोलन की आवश्यकता नहीं है, लेकिन जब तक कि आपने पर्ल 5.10.1 या बेहतर से 'ऑटोडी' प्रज्ञा का उपयोग नहीं किया है, तो आपने यह देखने के लिए रिटर्न वैल्यू की बेहतर जांच की है कि आपने कोई टाइपो नहीं बनाया है। 'PERL_UNICODE' भी उपलब्ध है, जिसे 'एस' पर सेट किया जा सकता है। आप इसे ** - C0 ** कमांड लाइन ध्वज का उपयोग कर रनटाइम पर ओवरराइड कर सकते हैं। अधिकतर आप इसे जोड़ना चाहेंगे, जैसे ** - सीएसएडी **। बस इसके साथ सावधान रहें, क्योंकि अब आपकी सभी अनमार्कित स्ट्रीम यूटीएफ -8 में डिफ़ॉल्ट हैं, जो अक्सर आपको नली बनाती हैं। तो यह एक अच्छा डिफ़ॉल्ट नहीं है। – tchrist

5

हालांकि यह एक पुराने सवाल है, मैं सिर्फ कई घंटे बिताए (!) और अधिक या कम एक ही बात करने के लिए कोशिश कर रहा! यही है: यूटीएफ -8 एक्सएमएल फ़ाइल से डेटा पढ़ें, और उस डेटा को विंडोज -1252 कोडपेज में परिवर्तित करें (मैं लैटिन 1, आईएसओ -885 9 -1 इत्यादि भी इस्तेमाल कर सकता था) ताकि उच्चारण अक्षरों वाले फाइलनाम बनाने में सक्षम हो सकें ।

अधिक प्रयोग के बाद, और और खोज, मैं अंत में रूपांतरण कार्य करने में कामयाब रहा। "चाल" एनकोड :: एनकोड :: डीकोड के बजाय एनकोड का उपयोग करना है।

उदाहरण के लिए, मूल प्रश्न में कोड को देखते हुए से कन्वर्ट करने के लिए सही (या कम से कम एक :-) तरह से UTF-8 होगा:

my $title = Encode::encode("Windows-1252", $item->{title}); 

या

my $title = Encode::encode("ISO-8859-1", $item->{title}); 

या

my $title = Encode::encode("<your-favourite-codepage-here>", $item->{title}); 

मुझे आशा है कि यह दूसरों के समान जनसंपर्क होने में मदद करता है oblems!