2013-02-18 15 views
7

क्यों निम्नलिखित js कोड शब्द:बग: देखने के आसपास यूनिकोड मुद्दे

"آرد@".replace(/(?=.)/g,'!'); // returns: ""!آ!ر!د"" 

लेकिन इसकी php बराबर रिटर्न '!�!�!�!�!�!�'?

preg_replace('/(?=.)/u', '!', 'آرد'); //returns '!�!�!�!�!�!�' 

यह केवल 4.3.5 - 5.0.5, 5.1.1 - 5.1.6 संस्करणों में काम करता है।

देखें: http://3v4l.org/jrV0W

+0

क्या @ PHP संस्करण में क्या करता है? यह भी "/(?=.)/" नहीं होना चाहिए? वास्तव में पूछना क्योंकि मैंने पहले यह नहीं देखा है। – kufudo

+1

'@' अमान्य डिलीमीटर है। [PHP] जांचें (http://www.php.net/manual/en/regexp.reference.delimiters.php) का डिलीमीटर पृष्ठ। – hjpotter92

+2

@BackinaFlash यह मान्य है! – PHPst

उत्तर

1

कुछ स्ट्रिंग का परीक्षण करने के बाद अब मुझे लगता है कि PREG इंजन में एक बग है। पहले तीन लाइन आउटपुट की उम्मीद थी, लेकिन चौथी लाइन दोषपूर्ण है।

<?php 
echo preg_replace('/./'  , '#', 'آرد') . PHP_EOL; //✓ 
echo preg_replace('/./u'  , '#', 'آرد') . PHP_EOL; //✓ 
echo preg_replace('/(?=.)/' , '#', 'آرد') . PHP_EOL; //✓ 
echo preg_replace('/(?=.)/u' , '#', 'آرد') . PHP_EOL; //✗ 
echo preg_replace('/(?=\pL)/' , '#', 'آرد') . PHP_EOL; //? 
echo preg_replace('/(?=\pL)/u', '#', 'آرد') . PHP_EOL; //? 

आउट कर दिया:

###### 
### 
#�#�#�#�#�#� 
#�#�#�#�#�#� 
#آ#ر#د 
#آ#ر#د 
+0

कोई बग नहीं है, किया क्या आप वास्तव में मेरा जवाब पढ़ते हैं? मैं समझाता हूं कि डॉट के साथ लाइन –

+0

@TomSarduy क्यों काम नहीं करती है जैसा कि आप मेरे उदाहरण में देखते हैं '/ ./ u' काम करता है जब यह एक नज़र में रखा जाता है। – PHPst

4

आप बस /u संशोधक जोड़ने, तो पैटर्न utf-8 रूप में व्यवहार किया जाता है। दूसरे उदाहरण काम करता है क्योंकि:

  1. पीएचपी 5.1 के बाद से, आप \p{L} के रूप में अनुवाद किया जा सकता है कि उपयोग कर सकते हैं: "किसी भी भाषा से पत्र के किसी भी प्रकार है।"
  2. मानक नोटेशन के अलावा, \ p {एल}, जावा, पर्ल, पीसीआरई और अब PHP आपको शॉर्टेंड \pL का उपयोग करने की अनुमति देता है। शॉर्टेंड केवल सिंगल-लेटर यूनिकोड गुणों के साथ काम करता है।

अद्यतन: क्यों preg_replace('/(?=.)/u', '!', 'آرد'); //returns '!�!�!�!�!�!�'??

@MarkFox कहते हैं, कारण यह है preg_replace() के संदर्भ में यह चरित्र प्रति एक बाइट और वर्ण आप "RegExing" कर रहे हैं मान लिया गया है multibyte हैं । यही कारण है कि आपके प्रतिस्थापन आउटपुट में आपके द्वारा अपेक्षित मिलानों को दोगुना कर दिया गया है, यह प्रत्येक वर्ण के प्रत्येक बाइट से मेल खाता है (जो मुझे दो बाइट्स होने का अनुमान है) -

कोई फर्क नहीं पड़ता कि आप अपने दस्तावेज़ एन्कोडिंग के साथ क्या करते हैं, आपको उपयोग करने की आवश्यकता होगी यह काम करने के लिए Unicode character properties

उस अजीब प्रतीक के बारे में क्या?

जब आप देखते हैं कि "अंदर एक प्रश्न चिह्न के साथ अजीब वर्ग प्रतीक" अन्यथा प्रतिस्थापन चरित्र के रूप में जाना जाता है, जो आम तौर पर एक संकेतक है कि आपके पास 80-एफएफ (128-255) की सीमा में बाइट है और सिस्टम UTF-8 में इसे प्रस्तुत करने का प्रयास कर रहा है।

कि पूरे बाइट-रेंज UTF-8 में एकल-बाइट वर्णों के लिए अमान्य है, लेकिन ISO-8859-1 जैसे पश्चिमी एन्कोडिंग में सभी बहुत आम हैं।

+2

देखें, उत्तर बताता है कि \ pL preg_replace के साथ क्यों काम करता है। डॉट 'कारण'। मेटाएक्टेक्टर विफल रहता है क्योंकि preg_replace के संदर्भ में यह प्रति बाइट एक बाइट मानता है और जिन अक्षरों को आप RegExing कर रहे हैं वे multibyte हैं। यही कारण है कि आपके प्रतिस्थापन आउटपुट में आपके द्वारा अपेक्षित मिलानों को दोगुना कर दिया गया है, यह प्रत्येक वर्ण के प्रत्येक बाइट से मेल खाता है (जिसे मैं दो बाइट्स का अनुमान लगाता हूं)। –

+0

@PHPst: वास्तव में, मार्कफ़ॉक्स बिल्कुल सही है, यह मेरे उत्तर का हिस्सा होगा: डी –

+0

@PHPst: क्या सच नहीं है? मुझे लगता है कि सभी –