2012-02-24 32 views
7

यह U क्यों प्रिंट करता है और Ü नहीं?ग्रैफेम पाने का सही तरीका क्या है?

#!/usr/bin/env perl 
use warnings; 
use 5.014; 
use utf8; 
binmode STDOUT, ':utf8'; 
use charnames qw(:full); 

my $string = "\N{LATIN CAPITAL LETTER U}\N{COMBINING DIAERESIS}"; 

while ($string =~ /(\X)/g) { 
     say $1; 
} 

# Output: U 
+0

यह [काम करता है] (http://ideone.com/tw9Qr) perl 5.12 पर। – jfs

+6

आपको इन चीजों को संख्याओं से खेलना होगा; भरोसा न करें कि "टर्मिनल" प्रदर्शित करता है। इसे [uniquote] (http://training.perl.com/scripts/uniquote) के माध्यम से पाइप करें, शायद '-x' या' -v' के साथ, और देखें कि यह वास्तव में क्या कर रहा है। आंखें धोखा देती हैं, और कार्यक्रम भी बदतर होते हैं। आपका टर्मिनल प्रोग्राम छोटी है, इसलिए आपसे झूठ बोल रही है। – tchrist

उत्तर

3

यह मेरे लिए काम करता है, हालांकि मैं पर्ल, 5.012 के एक पुराने संस्करण है, ubuntu पर। अपनी स्क्रिप्ट मेरे ही परिवर्तन है: use 5.012;

$ perl so.pl 
Ü 
+0

5.010 का उपयोग करें; नौकरी भी करता है उबंटू पर perl 5.012 के साथ परीक्षण किया; –

+0

यह केडीई से 'कंसोल' (2.7.2) के साथ काम नहीं किया। अब मैंने इसे 'xterm' के साथ करने की कोशिश की और वहां काम किया। –

1

मेरा सुझाव है मई यह उत्पादन जो सही नहीं है क्या है? यह जांचना आसान है: अपने लूप कोड को प्रतिस्थापित करें:

my $counter; 
while ($string =~ /(\X)/g) { 
    say ++$counter, ': ', $1; 
} 

... और देखें कि रेगेक्स कितनी बार मेल खाएगा। मेरा अनुमान है कि यह अभी भी एक बार मैच होगा।

वैकल्पिक रूप से, आप इस कोड का उपयोग कर सकते हैं:

use Encode; 
sub codepoint_hex { 
    sprintf "%04x", ord Encode::decode("UTF-8", shift); 
} 

... और फिर, जबकि पाश के भीतर बजाय सादे $ 1 का codepoint_hex ($ 1) मुद्रित करें।

+0

आपको लगभग एन्कोड/डीकोड को कभी भी कॉल नहीं करना चाहिए। – tchrist

+0

मुझे समझ में नहीं आता कि मुझे मैच को डीकोड क्यों करना चाहिए। –

+0

@sid_com आपको निश्चित रूप से नहीं करना चाहिए। सुझाव के लिए – tchrist

1

1) जाहिर है, आपका टर्मिनल विस्तारित वर्ण प्रदर्शित नहीं कर सकता है। मेरी टर्मिनल पर, यह प्रिंट:

2)\X आप क्या सोचते हैं यह करता है नहीं करता है। यह केवल उन पात्रों का चयन करता है जो एक साथ जाते हैं।

f 
u¨ 
r 

नोट कैसे विशेषक चिह्न अकेले मुद्रित नहीं है, लेकिन उसके संगत चरित्र के साथ: यदि आप स्ट्रिंग "fu\N{COMBINING DIAERESIS}r", अपने कार्यक्रम को प्रदर्शित करता है का उपयोग करते हैं।

3) एक में सभी संबंधित पात्रों गठबंधन करने के लिए, मॉड्यूल Unicode::Normalize का उपयोग करें:

use Unicode::Normalize; 

my $string = "fu\N{COMBINING DIAERESIS}r"; 
$string = NFC($string); 

while ($string =~ /(\X)/g) { 
    say $1; 
} 

यह प्रदर्शित करता है:

f 
ü 
r 
+1

** पहला: ** ऐसा नहीं है जो एनएफसी करता है। यह बस ऐसा करने के लिए होता है। यह कई अन्य चीजें करता है; लोग इसके सामान्य उपयोग और उद्देश्य के बारे में गलत हैं। ** SECOND: ** यदि आपका टर्मिनल प्रोग्राम सही ढंग से संयोजन अक्षरों को प्रदर्शित नहीं करेगा, तो यह अलग-अलग समकक्ष अनुक्रमों का अलग-अलग व्यवहार कर रहा है, जो बुरा और गलत है। यूनिकोड मानक के p.60 पर अनुरूपता आवश्यकता सी 6 देखें। तुम्हारी छोटी गाड़ी है: आपको इसे हटाने की ज़रूरत नहीं है, अन्यथा आप नहीं लिख सकते: 'perl -CS-mutf8 -MUnicode :: सामान्यीकृत -ई' स्केलर रिवर्स एनएफडी ("क्रेमे ब्रूली") '' => 'éelurb emerc'। – tchrist

+1

ध्यान दें कि "éelurb emerc" पर एनएफसी चलाना "सभी संबंधित पात्रों को एक में जोड़ नहीं देगा"। – tchrist

+1

आपको क्या लगता है कि वह सोचता है कि \ X' करता है? – tchrist

8

आपका कोड सही है।

आपको इन चीजों को संख्याओं से चलाने की ज़रूरत है; भरोसा न करें कि "टर्मिनल" प्रदर्शित करता है। इसे the uniquote program के माध्यम से पाइप करें, शायद -x या -v के साथ, और देखें कि यह वास्तव में क्या कर रहा है।

आंखें धोखा देती हैं, और कार्यक्रम भी बदतर होते हैं। आपका टर्मिनल प्रोग्राम छोटी है, इसलिए आपसे झूठ बोल रही है। सामान्यीकरण कोई फर्क नहीं पड़ता।

$ perl -CS -Mutf8 -MUnicode::Normalize -E 'say "crème brûlée"' 
crème brûlée 
$ perl -CS -Mutf8 -MUnicode::Normalize -E 'say "crème brûlée"' | uniquote -x 
cr\x{E8}me br\x{FB}l\x{E9}e 
$ perl -CS -Mutf8 -MUnicode::Normalize -E 'say NFD "crème brûlée"' 
crème brûlée 
$ perl -CS -Mutf8 -MUnicode::Normalize -E 'say NFD "crème brûlée"' | uniquote -x 
cre\x{300}me bru\x{302}le\x{301}e 

$ perl -CS -Mutf8 -MUnicode::Normalize -E 'say NFC scalar reverse NFD "crème brûlée"' 
éel̂urb em̀erc 
$ perl -CS -Mutf8 -MUnicode::Normalize -E 'say NFC scalar reverse NFD "crème brûlée")' | uniquote -x 
\x{E9}el\x{302}urb em\x{300}erc 
$ perl -CS -Mutf8 -MUnicode::Normalize -E 'say scalar reverse NFD "crème brûlée"' 
éel̂urb em̀erc 
$ perl -CS -Mutf8 -MUnicode::Normalize -E 'say scalar reverse NFD "crème brûlée"' | uniquote -x 
e\x{301}el\x{302}urb em\x{300}erc 
+0

मैं सहमत हूं। कोड में कोई बदलाव की आवश्यकता नहीं है। यह ओपी के टर्मिनल (और मेरा भी, डेबियन के केडीई 'कंसोल' के साथ एक मुद्दा है)। – ikegami

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