पिछले सप्ताह के लेख में, आपने एक छोटी प्रक्रिया सीखी जो अधिकांश एन्कोडिंग समस्याओं को हल करती है। लेकिन एक एन्कोडिंग समस्या है जिसे हल करना बहुत कठिन है।
मुझे पता है कि आपने इसे देखा है। (या शायद आपने इसे देखा है?) यह तब होता है जब एक घुँघराला उद्धरण "" में बदल जाता है, या एक एम-डैश "" में बदल जाता है। यह आपको सोचने पर मजबूर कर देगा कि आप पागल हो गए हैं। यह बस काम करना चाहिए!
आप एक विशाल तालिका बना सकते हैं, ताकि आप बुरे पात्रों को ढूंढ सकें और उन्हें अच्छे से बदल सकें:
[{broken: '–', fixed: "—"}
{broken: "—", fixed: "–"}
{broken: "‘", fixed: "‘"}
{broken: "’", fixed: "’"}
{broken: "“", fixed: "“"}
{broken: "â€", fixed: "”"}, ...]
लेकिन उन टूटे हुए पात्रों को ठीक करने का एक आसान, अधिक विश्वसनीय तरीका है।
अच्छी टाइपोग्राफी हमेशा क्यों टूटती है?
पिछले सप्ताह, आपने सीखा कि एन्कोडिंग अर्थहीन बाइट्स के समूहों को प्रदर्शित करने योग्य वर्णों में बदलने का एक तरीका है। प्रत्येक वर्ण को एक बाइट में प्रदर्शित नहीं किया जा सकता है, क्योंकि 256 से अधिक संभावित वर्ण हैं। तो कुछ अक्षर, जैसे कर्ली कोट ’
, एक से अधिक बाइट के साथ प्रदर्शित होते हैं:
irb(main):001:0> "they’re".bytes
=> [116, 104, 101, 121, 226, 128, 153, 114, 101]
भले ही स्ट्रिंग में केवल 7 वर्ण हों, वे 9 बाइट्स द्वारा दर्शाए जाते हैं!
जब आप केवल घुंघराले उद्धरण पर ध्यान केंद्रित करते हैं:
irb(main):002:0> "’".bytes
=> [226, 128, 153]
आप देखेंगे कि यह 3 बाइट्स का उपयोग करता है। और हमारी गड़बड़ स्ट्रिंग, वे फिर से, तीन वर्ण हैं जहां इसमें केवल एक होना चाहिए। यह एक संयोग से अधिक लगता है, है ना?
ऐसा लगता है कि उन तीन बाइट्स को UTF-8 के रूप में पढ़ा जाना चाहिए, जहां वे एक घुंघराले उद्धरण का प्रतिनिधित्व करेंगे। इसके बजाय, प्रत्येक बाइट एक अलग चरित्र के रूप में दिखाई दे रहा है। तो, कौन सा एन्कोडिंग [226, 128, 153]
represent का प्रतिनिधित्व करेगा ’
. के रूप में ? यदि आप लोकप्रिय एन्कोडिंग की कुछ तालिकाओं को देखें, तो आप देखेंगे कि यह Windows-1252 है।
आप इसे irb
. में देख सकते हैं :
irb(main):003:0> "they’re".force_encoding("Windows-1252").encode("UTF-8")
=> "they’re"
(हमें उस अंतिम .encode("UTF-8")
. की आवश्यकता है कंसोल में स्ट्रिंग प्रदर्शित करने के लिए।)
<मजबूत>हाँ! यही समस्या है। लेकिन यह बदतर हो जाता है।
डेटा को UTF-8 माना जाता है, लेकिन इसे Windows-1252 के रूप में गलत पढ़ा जा रहा है। लेकिन आप शायद उस डेटा को यूटीएफ -8 के रूप में डेटाबेस या फ़ाइल में सहेज लेंगे। रूबी आपके लिए इसे UTF-8 में मददगार रूप से रूपांतरित करेगा, इसलिए आपके पास यह होगा:
irb(main):004:0> "they’re".force_encoding("Windows-1252").encode("UTF-8")
=> "they’re"
irb(main):005:0> "they’re".force_encoding("Windows-1252").encode("UTF-8").bytes
=> [116, 104, 101, 121, 195, 162, 226, 130, 172, 226, 132, 162, 114, 101]
आपकी स्ट्रिंग को दो बार बुरी तरह से एन्कोड किया गया है . वे टूटे हुए पात्र अब ऐसे दिखते हैं जैसे उन्हें वहाँ होना चाहिए था। और अगर आप नहीं जानते कि यह कैसे हुआ, तो इसे सुलझाना लगभग असंभव होगा।
आप इसे कैसे ठीक करते हैं?
आप चीजों को वापस सामान्य कैसे प्राप्त करते हैं? आइए समस्या के बारे में पीछे की ओर सोचें:
-
आपके पास एक UTF-8 स्ट्रिंग है, (वे फिर से)
-
Windows-1252 स्ट्रिंग से रूपांतरित, (वे पुनः)
-
जिसका बाइट होना चाहिए था UTF-8 के रूप में पढ़ें (वे हैं)
इसे ठीक करने के लिए, आपको बस उन पिछले चरणों का पालन करना होगा। encode
का उपयोग करें UTF-8 स्ट्रिंग को वापस Windows-1252 स्ट्रिंग में बदलने के लिए। फिर, force_encoding
का उपयोग करें उस गलत एन्कोडेड Windows-1252 स्ट्रिंग को UTF-8 के रूप में पढ़ने के लिए बाध्य करने के लिए:
irb(main):006:0> "they’re".encode("Windows-1252").force_encoding("UTF-8")
=> "they’re"
फिक्स्ड!
एक छोटी सी समस्या है...
दुर्भाग्य से, आपको शायद यह समस्या इसलिए मिली क्योंकि फाइलों या डेटाबेस रिकॉर्ड्स के एक समूह में डेटा को बुरी तरह से एन्कोड किया गया था। और जरूरी नहीं कि हर फ़ाइल या रिकॉर्ड बुरी तरह से एन्कोड किया गया हो - आपके पास अच्छे और बुरे डेटा का मिश्रण हो सकता है। विशेष रूप से अगर वह डेटा आपकी साइट पर आने वाले लोगों से आया है।
अगर ऐसा है, तो आप उस कोड को हर स्ट्रिंग पर आँख बंद करके नहीं चला सकते:
irb(main):007:0> "they’re".encode("Windows-1252").force_encoding("UTF-8")
=> "they’re"
irb(main):008:0> "they’re".encode("Windows-1252").force_encoding("UTF-8")
=> "they\x92re"
यदि आप इसे अच्छे डेटा पर चलाते हैं, तो आप इसे केवल खराब डेटा में बदल देंगे। तो आप क्या कर सकते हैं?
आप अनुमानी का उपयोग कर सकते हैं:केवल उन स्ट्रिंग्स को बदलें जिनमें उनमें से एक खराब वर्ण हो, जैसे â
. यह अच्छी तरह से काम करता है अगर एक चरित्र जैसे â
मान्य स्ट्रिंग में कभी भी प्रकट नहीं होगा।
पिछली बार जब मैंने इस तरह के बग को ठीक किया था, हालांकि, मैं इसे सुरक्षित रूप से खेलना चाहता था। मैंने मदद करने के लिए एक और उपयोगी उपकरण का उपयोग किया:मेरी आंखें।
जब भी मुझे एक बुरी तरह से एन्कोडेड स्ट्रिंग मिली, तो मैंने इसे इसके प्रतिस्थापन के साथ प्रिंट कर लिया:
Changing title with ID 6 from "They’re over there!" to "They’re over there!"
इस तरह, मैं बदली हुई स्ट्रिंग्स की छोटी संख्या को स्पॉट-चेक कर सकता था, और सुनिश्चित कर सकता था कि वे आगे नहीं टूटे।
मुझे लगता है कि मुझे सिरदर्द है
जैसा कि मैंने पिछले सप्ताह कहा था, एक ही डेटा की विभिन्न व्याख्याओं को सीधे अपने दिमाग में रखना कठिन है! लेकिन अगर आप भ्रमित हैं, तो irb
. में एक्सप्लोर करें कंसोल मदद करेगा। तो इसे आजमाएं! एक को खोलें, और देखें कि क्या आप —
. के बीच आगे-पीछे जा सकते हैं और —
, या “
और “
।
इस तरह के जटिल विचारों का अभ्यास करना जरूरत पड़ने पर आत्मविश्वास महसूस करने का सबसे तेज़ तरीका है। और प्रैक्टिसिंग रेल्स . के फ्री सैंपल चैप्टर में , आप ऐसा करने के लिए सर्वोत्तम तकनीकों और प्रक्रियाओं को सीखेंगे।