अदृश्य Unicode अक्षर कोई दिखने वाली जगह नहीं घेरते, फिर भी स्ट्रिंग का हिस्सा रहते हैं। आम अक्षरों में ज़ीरो-विथ स्पेस, सॉफ्ट हाइफ़न, बाइट-ऑर्डर मार्क, नॉन-ब्रेकिंग स्पेस और दिशा चिह्न शामिल हैं। हर एक का कोई वैध टाइपोग्राफ़िक काम है, और हर एक कॉपी-पेस्ट में बचकर आगे बढ़ने पर सर्च, वैलिडेशन, पार्सिंग और डुप्लिकेट हटाने की प्रक्रिया तोड़ देता है।
वे अक्षर जो असल में आपको मिलेंगे
| अक्षर | कोड पॉइंट | काम | क्या बिगाड़ता है |
|---|---|---|---|
| ज़ीरो-विथ स्पेस | U+200B | लाइन-ब्रेक की जगह सुझाता है | सर्च, स्ट्रिंग तुलना |
| ज़ीरो-विथ नॉन-जॉइनर | U+200C | अक्षरों को जुड़ने से रोकता है | लिगेचर, अरबी और भारतीय लिपियों का टेक्स्ट |
| ज़ीरो-विथ जॉइनर | U+200D | अक्षरों को जबरन जोड़ता है | इमोजी सीक्वेंस, टेक्स्ट की लंबाई |
| सॉफ्ट हाइफ़न | U+00AD | रैप होने पर ही दिखने वाला हाइफ़न | सर्च, कॉपी किया टेक्स्ट |
| नॉन-ब्रेकिंग स्पेस | U+00A0 | कभी न रैप होने वाली स्पेस | ट्रिमिंग, CSV पार्सिंग, कोड |
| नैरो नो-ब्रेक स्पेस | U+202F | विराम चिह्न से पहले पतली स्पेस | ऊपर जैसा ही |
| बाइट-ऑर्डर मार्क | U+FEFF | फ़ाइल की शुरुआत में एन्कोडिंग बताता है | CSV का पहला कॉलम, JSON पार्सिंग |
| वर्ड जॉइनर | U+2060 | बिना चौड़ाई के ब्रेक रोकता है | सर्च |
| लेफ़्ट-टू-राइट मार्क | U+200E | टेक्स्ट की दिशा तय करता है | दिखने का क्रम, ट्रिमिंग |
| राइट-टू-लेफ़्ट मार्क | U+200F | टेक्स्ट की दिशा तय करता है | दिखने का क्रम |
| RTL ओवरराइड | U+202E | दाएँ-से-बाएँ दिखाने पर मजबूर करता है | फ़ाइलनाम धोखाधड़ी |
| लाइन सेपरेटर | U+2028 | Unicode लाइन ब्रेक | JavaScript स्ट्रिंग लिटरल |
| पैराग्राफ़ सेपरेटर | U+2029 | Unicode पैराग्राफ़ ब्रेक | पुराने पार्सर में JSON |
इनमें से हर एक का कोई असली काम है। समस्या इनके होने में कभी नहीं है — समस्या यह है कि ये चुपचाप उन सिस्टमों के बीच घूमते रहते हैं जो इन्हें अलग-अलग तरीके से देखते हैं।
ये कहाँ से आते हैं
- वेबपेज से कॉपी करना। साइटें लंबी स्ट्रिंग कहाँ रैप हो, यह तय करने के लिए ज़ीरो-विथ स्पेस डालती हैं और जस्टिफ़ाइड टेक्स्ट के लिए सॉफ्ट हाइफ़न। कॉपी के साथ दोनों साथ चलते हैं।
- वर्ड प्रोसेसर। नॉन-ब्रेकिंग स्पेस अपने आप डाल दी जाती हैं ताकि संख्या अपनी इकाई के साथ या कोई नाम एक ही लाइन में रहे।
- PDF एक्सट्रैक्शन। PDF से कॉपी करने पर अक्सर वहाँ सॉफ्ट हाइफ़न आ जाते हैं जहाँ टाइपसेटर ने शब्दों को लाइनों में तोड़ा था, साथ ही जस्टिफ़ाइड स्पेसिंग से नॉन-ब्रेकिंग स्पेस भी।
- AI चैट इंटरफ़ेस। आउटपुट HTML के रूप में रेंडर होता है, इसलिए कॉपी करने पर जो भी स्पेसिंग अक्षर उस फ़ॉर्मैटिंग में लगे थे वे साथ आ जाते हैं — आमतौर पर U+00A0 और U+202F।
- एन्कोडिंग बदलाव। जब कोई फ़ाइल UTF-8 with BOM के रूप में सेव होती है तो बाइट-ऑर्डर मार्क आ जाता है — Windows पर यह आम बात है।
- जानबूझकर डालना। लीक का पता लगाने के लिए दस्तावेज़ों में फ़िंगरप्रिंट बनाने और कीवर्ड फ़िल्टर से बचकर टेक्स्ट निकालने के लिए भी ज़ीरो-विथ अक्षरों का इस्तेमाल हुआ है।
पैटर्न हमेशा एक जैसा है: ये तब घुसते हैं जब टेक्स्ट किसी प्रेज़ेंटेशन संदर्भ से डेटा संदर्भ में जाता है।
ये चीज़ें कैसे बिगाड़ते हैं
सर्च चुपचाप फेल हो जाता है। किसी शब्द के अंदर ज़ीरो-विथ स्पेस होने पर उसे खोजने पर कुछ नहीं मिलता। वजह का कोई संकेत नहीं मिलता — शब्द तो साफ़-साफ़ वहीं दिख रहा है।
वैलिडेशन सही इनपुट को ठुकरा देती है। ईमेल पते के आख़िर में नॉन-ब्रेकिंग स्पेस लगी हो तो फ़ॉर्मैट जाँच फेल हो जाती है। उपयोगकर्ता के सामने सही पता होता है और ऐसा एरर संदेश जिसका कोई मतलब नहीं बनता।
तुलना फेल हो जाती है। "Ada" === "Ada\u200B" गलत है। डुप्लिकेट हटाने की प्रक्रिया साफ़-साफ़ दिखने वाले डुप्लिकेट भी छोड़ देती है; लुकअप कुछ नहीं लाते; जॉइन में पंक्तियाँ गिर जाती हैं।
ट्रिमिंग भी मदद नहीं करती। ज़्यादातर trim() लागू करने के तरीके सिर्फ़ ASCII व्हाइटस्पेस हटाते हैं। कई भाषाओं में नॉन-ब्रेकिंग स्पेस .trim() से भी बच जाती है — यही वजह है कि "मैंने तो पहले ही ट्रिम कर दिया था" इतना आम बंद रास्ता है।
कोड कम्पाइल नहीं होता। जहाँ साधारण स्पेस होनी चाहिए वहाँ नॉन-ब्रेकिंग स्पेस हो तो ऐसी लाइन पर सिंटैक्स एरर आता है जो देखने में बिल्कुल सही लगती है।
CSV इम्पोर्ट बिगड़ जाता है। बाइट-ऑर्डर मार्क पहले हेडर से चिपक जाता है, इसलिए id बन जाता है \uFEFFid और पहला कॉलम चुपचाप मैप नहीं होता।
लंबाई गलत निकलती है। इमोजी सीक्वेंस में ज़ीरो-विथ जॉइनर का मतलब है कि एक दिखने वाला इमोजी कई कोड पॉइंट का हो सकता है, इसलिए अक्षर सीमा ऐसे इनपुट को ठुकरा देती है जो सीमा के अंदर लगता है।
फ़ाइलनाम धोखा दे सकते हैं। U+202E दिखने वाले टेक्स्ट को उलट देता है, इसलिए report\u202Egnp.exe को reportexe.png की तरह दिखाया जा सकता है। यह सिर्फ़ जिज्ञासा नहीं, असली सुरक्षा चिंता है।
इन्हें खोजना और हटाना
पहले स्कैन करें। टेक्स्ट को अदृश्य अक्षर स्कैनर में पेस्ट करें। यह बताता है कि किस तरह के अक्षर मौजूद हैं और हर तरह के कितने, फिर माँगने पर उन्हें हटा देता है। पहले गिनती देखने से पता चलता है कि सामने एक आवारा अक्षर है या व्यवस्थित दूषण।
किसी एडिटर में। VS Code अपनी unicode-highlight सेटिंग से ज़्यादातर अदृश्य अक्षरों को डिफ़ॉल्ट रूप से हाइलाइट करता है। regex वाले find-and-replace के लिए यह पैटर्न आम सेट को पकड़ लेता है:
[\u200B-\u200F\u00AD\uFEFF\u2060\u202A-\u202E\u2028\u2029]
कोड में, सीमा पर नॉर्मलाइज़ करें — डेटा के आते ही, न कि इस्तेमाल के समय:
const clean = input
.replace(/[\u200B-\u200F\u2060\uFEFF\u00AD\u202A-\u202E]/g, "")
.replace(/[\u00A0\u202F]/g, " ")
.normalize("NFC")
.trim();
दो-चरणीय तरीके पर ध्यान दें: ज़ीरो-विथ अक्षर हटा दिए जाते हैं, लेकिन नॉन-ब्रेकिंग स्पेस को साधारण स्पेस में बदला जाता है — उन्हें हटा देने से शब्द आपस में जुड़ जाएँगे।
आँख बंद करके न हटाएँ। ज़ीरो-विथ जॉइनर इमोजी सीक्वेंस में और अरबी, फ़ारसी तथा कई भारतीय लिपियों में ज़रूरी होते हैं, जहाँ इन्हें हटाने से शब्दों का रेंडर बदल जाता है। पहचानकर्ताओं, कीज़ और कोड में सख़्ती से हटाएँ; उपयोगकर्ता के सामने जाने वाली सामग्री में संभलकर हटाएँ।
इस विशिष्ट सवाल के लिए कि क्या AI टूल जानबूझकर ये अक्षर डालते हैं, देखें क्या ChatGPT अदृश्य अक्षर छिपाता है। दिखने वाला लेकिन उतना ही नुकसान पहुँचाने वाला समतुल्य मामला घुमावदार उद्धरण कोड क्यों तोड़ते हैं में बताया गया है।
अक्सर पूछे जाने वाले सवाल
ज़ीरो-विथ स्पेस क्या होता है?
U+200B, एक ऐसा अक्षर जो कोई दिखने वाली चौड़ाई नहीं लेता, फिर भी स्ट्रिंग का हिस्सा रहता है। वेबसाइटें इसे यह सुझाने के लिए इस्तेमाल करती हैं कि लंबा शब्द कहाँ रैप हो सकता है। यह सर्च और स्ट्रिंग तुलना तोड़ देता है, क्योंकि टेक्स्ट एक जैसा दिखता है जबकि नीचे के बाइट अलग होते हैं।
जो टेक्स्ट साफ़-साफ़ मौजूद है, उस पर मेरा सर्च क्यों फेल होता है?
लगभग पक्का है कि शब्द के अंदर कोई अदृश्य अक्षर है — आमतौर पर ज़ीरो-विथ स्पेस या सॉफ्ट हाइफ़न, जो किसी वेबपेज या PDF से आया हो। रेंडर हुआ टेक्स्ट आपके टाइप किए से मेल खाता है, लेकिन असली स्ट्रिंग नहीं खाती।
क्या trim() नॉन-ब्रेकिंग स्पेस हटा देता है?
आमतौर पर नहीं। ज़्यादातर trim लागू करने के तरीके सिर्फ़ ASCII व्हाइटस्पेस हटाते हैं, इसलिए नॉन-ब्रेकिंग स्पेस (U+00A0) बच जाती है। यही वजह है कि जो इनपुट देखने में बिना शुरुआती या आख़िरी स्पेस का लगता है, वह ट्रिम करने के बाद भी वैलिडेशन में फेल हो जाता है।
टेक्स्ट से अदृश्य अक्षर कैसे हटाऊँ?
इसे किसी ऐसे स्कैनर में पेस्ट करें जो इन्हें सूचीबद्ध करके हटा दे, या U+200B–U+200F, U+00AD, U+FEFF, U+2060 और U+202A–U+202E को ढकने वाला regex इस्तेमाल करें। ज़ीरो-विथ अक्षर हटा दें, लेकिन नॉन-ब्रेकिंग स्पेस को हटाने के बजाय साधारण स्पेस में बदलें, वरना शब्द आपस में जुड़ जाएँगे।
क्या अदृश्य अक्षर कभी उपयोगी भी होते हैं?
हाँ। सॉफ्ट हाइफ़न जस्टिफ़ाइड टेक्स्ट में शब्दों के टूटने को नियंत्रित करते हैं, नॉन-ब्रेकिंग स्पेस वैल्यू को उसकी इकाई के साथ रखती हैं, और ज़ीरो-विथ जॉइनर इमोजी सीक्वेंस और अरबी, फ़ारसी तथा भारतीय लिपियों के लिए ज़रूरी हैं। कोड और पहचानकर्ताओं में सख़्ती से हटाएँ, गद्य में संभलकर।