मैं बच गए यूनिकोड के साथ एक स्ट्रिंग को कैसे डीकोड कर सकता हूं?


89

मुझे यकीन नहीं है कि इसे क्या कहा जाता है इसलिए मुझे इसे खोजने में परेशानी हो रही है। मैं कैसे से यूनिकोड के साथ स्ट्रिंग डीकोड कर सकते हैं http\u00253A\u00252F\u00252Fexample.comकरने के लिए http://example.comजावास्क्रिप्ट के साथ? मैंने कोशिश की unescape, decodeURIऔर decodeURIComponentइसलिए मुझे लगता है कि केवल एक चीज बची है, वह है स्ट्रिंग की जगह।

संपादित करें: स्ट्रिंग टाइप नहीं किया गया है, बल्कि कोड के किसी अन्य टुकड़े से एक विकल्प है। तो समस्या को हल करने के लिए आपको कुछ इस तरह से शुरू करना होगा:

var s = 'http\\u00253A\\u00252F\\u00252Fexample.com';

मुझे उम्मीद है कि पता चलता है कि क्यों unescape () काम नहीं करता है।


तार कहाँ से आता है?
कैमरून

@Cameron: स्ट्रिंग एक स्क्रिप्ट से है जिसे मैंने पाने के लिए इनरएचटीएमएल कहा है। यही कारण है कि एलेक्स का जवाब काम नहीं करता है।
स्टाइलफेल

जवाबों:


109

संपादित करें (2017-10-12) :

@MechaLynx और @ केविन-वेबर नोट जो unescape()गैर-ब्राउज़र वातावरण से हटाए गए हैं और टाइपस्क्रिप्ट में मौजूद नहीं हैं। decodeURIComponentएक ड्रॉप-इन प्रतिस्थापन है। व्यापक संगतता के लिए, इसके बजाय नीचे का उपयोग करें:

decodeURIComponent(JSON.parse('"http\\u00253A\\u00252F\\u00252Fexample.com"'));
> 'http://example.com'

मूल उत्तर:

unescape(JSON.parse('"http\\u00253A\\u00252F\\u00252Fexample.com"'));
> 'http://example.com'

आप सभी कामों को बंद कर सकते हैं JSON.parse


6
दिलचस्प। मुझे इसके आस-पास के उद्धरणों को जोड़ना पड़ा unescape(JSON.parse('"' + s + '"'));। अतिरिक्त उद्धरणों का कारण क्या है? क्या यह वैध JSON बनाता है?
स्टाइल

1
ध्यान दें कि यह fromCharCodeदृष्टिकोण की तुलना में काफी तेज प्रतीत होता है : jsperf.com/unicode-func-vs-json-parse
nrabinowitz

17
@ स्टाइलफ के जवाब के बारे में महत्वपूर्ण नोट: इसके बजाय JSON.parse('"' + s + '"')अविश्वसनीय डेटा उपयोग से निपटने के दौरान उपयोग न करें JSON.parse('"' + s.replace('"', '\\"') + '"'), अन्यथा इनपुट के उद्धरण होने पर आपका कोड टूट जाएगा
ntninja

7
शानदार उत्तर @ alexander255, लेकिन आप वास्तव में उपयोग करना चाहेंगे: JSON.parse ('' '+ str.replace (/ \ "/ g,' \\" '' '' ') उस वर्ण के सभी आवृत्तियों को बदलने के लिए स्ट्रिंग, बजाय एक को बदलने के।
CS

2
उन लोगों के लिए जो इस बात से चिंतित हैं और क्योंकि वे unescape()पदावनत हो चुके हैं, इस मामले में decodeURIComponent()पहचान के साथ काम करते हैं unescape(), इसलिए बस इसे उसके साथ बदलें और आप अच्छे हैं।
मेकलेनक्स

116

अद्यतन : कृपया ध्यान दें कि यह एक समाधान है जो पुराने ब्राउज़रों या गैर-ब्राउज़र प्लेटफार्मों पर लागू होना चाहिए, और अनुदेशात्मक उद्देश्यों के लिए जीवित रखा जाना चाहिए। कृपया नीचे दिए गए उत्तर के लिए और अधिक @ @ उत्तर के लिए देखें।


यह एक यूनिकोड है, फरार स्ट्रिंग है। पहले तार बच गया, फिर यूनिकोड से एनकोड किया गया। वापस सामान्य में बदलने के लिए:

var x = "http\\u00253A\\u00252F\\u00252Fexample.com";
var r = /\\u([\d\w]{4})/gi;
x = x.replace(r, function (match, grp) {
    return String.fromCharCode(parseInt(grp, 16)); } );
console.log(x);  // http%3A%2F%2Fexample.com
x = unescape(x);
console.log(x);  // http://example.com

समझाने के लिए: मैं देखने के लिए एक नियमित अभिव्यक्ति का उपयोग करता हूं \u0025। हालांकि, बाद से मैं अपने को बदलने के ऑपरेशन के लिए इस स्ट्रिंग का केवल एक हिस्सा जरूरत है, मैं कोष्ठक, का उपयोग हिस्सा मैं पुन: उपयोग के लिए जा रहा हूँ अलग करने के लिए 0025। इस अलग-थलग भाग को एक समूह कहा जाता है।

giअभिव्यक्ति के अंत में भाग को दर्शाता है यह, बस नहीं पहले एक स्ट्रिंग में सभी उदाहरणों से मेल खाना चाहिए, और मिलान केस संवेदी होना चाहिए। यह उदाहरण दिया गया अनावश्यक लग सकता है, लेकिन यह बहुमुखी प्रतिभा जोड़ता है।

अब, एक स्ट्रिंग से अगले में बदलने के लिए, मुझे प्रत्येक मैच के प्रत्येक समूह पर कुछ चरणों को निष्पादित करने की आवश्यकता है, और मैं केवल स्ट्रिंग को परिवर्तित करके ऐसा नहीं कर सकता। सहायक रूप से, String.replace ऑपरेशन एक फ़ंक्शन को स्वीकार कर सकता है, जिसे प्रत्येक मैच के लिए निष्पादित किया जाएगा। उस फ़ंक्शन की वापसी मैच को स्ट्रिंग में ही बदल देगी।

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


3
धन्यवाद। क्या आप थोड़ा सा समझा सकते हैं कि आप क्या कर रहे हैं? ऐसा लगता है कि रेगेक्स एक \uउपसर्ग की तलाश में है और एक 4 वर्ण हेक्स संख्या (अक्षर या संख्या) से है। प्रतिस्थापन विधि में कार्य कैसे होता है?
स्टाइलऑक्ट

1
आप सही हैं, इसके लिए स्पष्टीकरण की आवश्यकता है, इसलिए मैंने अपनी पोस्ट अपडेट की है। का आनंद लें!
Ioannis Karadimas

1
महान समाधान। मेरे मामले में, मैं सर्वर से भेजे जा रहे सभी अंतर्राष्ट्रीय (गैर-एससीआई) वर्णों को कूटबद्ध कर रहा हूं क्योंकि यूनिकोड से बच गए हैं, फिर अपने फ़ंक्शन का उपयोग करके ब्राउज़र को सही UTF-8 वर्णों को डिकोड करने के लिए उपयोग कर रहे हैं। मैंने पाया कि मुझे सभी भाषाओं के पात्रों (अर्थात थाई) को पकड़ने के लिए निम्न regex को अपडेट करना था:var r = /\\u([\d\w]{1,})/gi;
नाथन हन्ना

2
ध्यान दें कि यह JSON.parseदृष्टिकोण की तुलना में काफी धीमा प्रतीत होता है : jsperf.com/unicode-func-vs-json-parse
nrabinowitz

1
@IoannisKaradimas वहाँ सबसे निश्चित रूप से जावास्क्रिप्ट में पदावनति जैसी बात है। ऐसा दावा करने के लिए और फिर इसे यह कहकर समर्थन करें कि पुराने ब्राउज़रों का हमेशा समर्थन किया जाना चाहिए, यह एक पूरी तरह से अहंकारी परिप्रेक्ष्य है। किसी भी मामले में, जो कोई भी इस का उपयोग करने और चाहता भी से बचने के लिए चाहता है unescape()का उपयोग कर सकते decodeURIComponent()बजाय। यह इस मामले में पहचान का काम करता है। मैं रेडिकैंड के दृष्टिकोण की सिफारिश करूंगा, क्योंकि यह सरल है, बस समर्थित और तेजी से निष्पादित करने के लिए, उसी परिणाम के साथ (हालांकि टिप्पणियों को पढ़ना सुनिश्चित करें)।
मेकलेनक्स

21

ध्यान दें कि के उपयोग unescape()है पदावनत और टाइपप्रति संकलक के साथ काम नहीं करता है, उदाहरण के लिए।

रेडिकैंड के जवाब और नीचे टिप्पणी अनुभाग के आधार पर, यहां एक अद्यतन समाधान है:

var string = "http\\u00253A\\u00252F\\u00252Fexample.com";
decodeURIComponent(JSON.parse('"' + string.replace(/\"/g, '\\"') + '"'));

http://example.com


यह कुछ स्ट्रिंग्स के लिए काम नहीं करता है, क्योंकि उद्धरण JSON स्ट्रिंग को तोड़ सकते हैं और परिणाम JSON पार्सिंग त्रुटियों में हो सकते हैं। मैंने इन मामलों में अन्य उत्तर ( stackoverflow.com/a/7885499/249327 ) का उपयोग किया ।
निकडोस

2

मेरे पास मौजूदा उत्तरों पर टिप्पणियों के तहत इसे डालने के लिए पर्याप्त प्रतिनिधि नहीं है:

unescapeकेवल URI (या किसी भी एन्कोडेड utf-8) के साथ काम करने के लिए पदावनत किया जाता है, जो कि शायद ज्यादातर लोगों की जरूरतों के लिए मामला है। encodeURIComponentबच निकलने के लिए एक js स्ट्रिंग परिवर्तित decodeURIComponentकरता है और केवल UTF-8 बाइट्स पर काम करता है। यह कुछ इस तरह के लिए एक त्रुटि फेंकता है decodeURIComponent('%a9'); // errorक्योंकि विस्तारित ascii मान्य utf-8 नहीं है (भले ही यह अभी भी एक यूनिकोड मान है), जबकि unescape('%a9'); // ©इसलिए आपको डिकोड्यूरिकम्पोनेंट का उपयोग करते समय अपने डेटा को जानना होगा।

DecodeURIComponent utf-8 में एक सरोगेट के भाग को इंगित करने वाले पर "%C2"या किसी भी अकेली बाइट पर काम नहीं करेगा 0x7f। हालाँकि decodeURIComponent("%C2%A9") //gives you ©Unescape उस पर ठीक से काम नहीं करेगा // ©और यह कोई त्रुटि नहीं करेगा, इसलिए यदि आप अपने डेटा को नहीं जानते हैं तो unescape छोटी गाड़ी कोड ले सकता है।


1

इसके लिए उपयोग में JSON.decodeमहत्वपूर्ण कमियां हैं जिनसे आपको अवगत होना चाहिए:

  • आपको स्ट्रिंग को डबल कोट्स में लपेटना होगा
  • कई पात्रों का समर्थन नहीं किया जाता है और खुद को बच जाना चाहिए। उदाहरण के लिए, करने के लिए निम्न में से कोई गुजर JSON.decode(उनमें दोहरे उद्धरण में लपेटकर के बाद) भले ही इन सभी मान्य हैं त्रुटि देगा: \\n, \n, \\0,a"a
  • यह हेक्साडेसिमल से बचने का समर्थन नहीं करता है: \\x45
  • यह यूनिकोड कोड बिंदु अनुक्रमों का समर्थन नहीं करता है: \\u{045}

वहाँ अन्य caveats भी हैं। अनिवार्य रूप से, JSON.decodeइस उद्देश्य के लिए उपयोग करना एक हैक है और वह काम नहीं करता है जिस तरह से आप हमेशा उम्मीद कर सकते हैं। आपको JSONJSON को संभालने के लिए लाइब्रेरी का उपयोग करने के साथ रहना चाहिए , न कि स्ट्रिंग संचालन के लिए।


मैं हाल ही में इस मुद्दे पर स्वयं गया था और एक मजबूत डिकोडर चाहता था, इसलिए मैंने खुद को लिखना समाप्त कर दिया। यह पूर्ण और अच्छी तरह से परीक्षण है और यहां उपलब्ध है: https://github.com/iansan5653/unraw । यह जावास्क्रिप्ट मानक की यथासंभव निकटता की नकल करता है।

स्पष्टीकरण:

स्रोत लगभग 250 रेखाएँ हैं इसलिए मैं इसे यहाँ सब शामिल नहीं करूँगा, लेकिन अनिवार्य रूप से यह सभी एस्केप अनुक्रमों को खोजने के लिए निम्न रेगेक्स का उपयोग करता है और फिर parseInt(string, 16)आधार -16 संख्याओं को डिकोड String.fromCodePoint(number)करने के लिए और फिर संबंधित वर्ण प्राप्त करने के लिए उनका उपयोग करता है :

/\\(?:(\\)|x([\s\S]{0,2})|u(\{[^}]*\}?)|u([\s\S]{4})\\u([^{][\s\S]{0,3})|u([\s\S]{0,4})|([0-3]?[0-7]{1,2})|([\s\S])|$)/g

टिप्पणी (नोट: यह regex सभी से बचने के अनुक्रमों से मेल खाता है, जिसमें अमान्य भी शामिल हैं। यदि स्ट्रिंग JS में कोई त्रुटि फेंकती है, तो यह मेरी लाइब्रेरी में एक त्रुटि फेंकता है (यानी, '\x!!'त्रुटि होगी]):

/
\\ # All escape sequences start with a backslash
(?: # Starts a group of 'or' statements
(\\) # If a second backslash is encountered, stop there (it's an escaped slash)
| # or
x([\s\S]{0,2}) # Match valid hexadecimal sequences
| # or
u(\{[^}]*\}?) # Match valid code point sequences
| # or
u([\s\S]{4})\\u([^{][\s\S]{0,3}) # Match surrogate code points which get parsed together
| # or
u([\s\S]{0,4}) # Match non-surrogate Unicode sequences
| # or
([0-3]?[0-7]{1,2}) # Match deprecated octal sequences
| # or
([\s\S]) # Match anything else ('.' doesn't match newlines)
| # or
$ # Match the end of the string
) # End the group of 'or' statements
/g # Match as many instances as there are

उदाहरण

उस पुस्तकालय का उपयोग करना:

import unraw from "unraw";

let step1 = unraw('http\\u00253A\\u00252F\\u00252Fexample.com');
// yields "http%3A%2F%2Fexample.com"
// Then you can use decodeURIComponent to further decode it:
let step2 = decodeURIComponent(step1);
// yields http://example.com
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.