मुझे सूक्ष्म विमान कोड बिंदुओं या अंतर्राष्ट्रीयकरण से संबंधित मुद्दों के मौजूदा उत्तरों में कोई उल्लेख नहीं मिला । "अपरकेस" का मतलब हर भाषा में दी गई स्क्रिप्ट का उपयोग करना नहीं है।
प्रारंभ में मैंने सूक्ष्म विमान कोड बिंदुओं से संबंधित मुद्दों को संबोधित करने वाले किसी भी उत्तर को नहीं देखा था। वहाँ एक है , लेकिन यह एक बिट दफन है (यह एक तरह होगा, मुझे लगता है!)
अधिकांश प्रस्तावित कार्य इस तरह दिखते हैं:
function capitalizeFirstLetter(str) {
return str[0].toUpperCase() + str.slice(1);
}
हालांकि, कुछ कैम्ड वर्ण बीएमपी (मूल बहुभाषी विमान, कोड अंक U + 0 से U + FFFF) के बाहर आते हैं। उदाहरण के लिए इस डिस्सेट टेक्स्ट को लें:
capitalizeFirstLetter("𐐶𐐲𐑌𐐼𐐲𐑉"); // "𐐶𐐲𐑌𐐼𐐲𐑉"
यहाँ पहला वर्ण भुनाने में विफल रहता है क्योंकि स्ट्रिंग्स के सरणी-अनुक्रमित गुण "वर्ण" या कोड पॉइंट * तक नहीं पहुँचते हैं। वे UTF-16 कोड इकाइयों का उपयोग करते हैं। यह तब भी सच है जब टुकड़ा करने की क्रिया - सूचकांक मान कोड इकाइयों पर इंगित करते हैं।
ऐसा होता है कि यूटीएफ -16 कोड इकाइयां 1: 1 के साथ दो श्रेणियों के भीतर यूएसवी कोड अंकों के साथ यू + 0 से यू + डी 7 एफएफ और यू + ई 1000 से यू + एफएफएफ समावेशी हैं। अधिकांश आवरण पात्र उन दो श्रेणियों में आते हैं, लेकिन वे सभी नहीं।
ES2015 से, इससे निपटना थोड़ा आसान हो गया। String.prototype[@@iterator]
कोड अंक के अनुरूप पैदावार स्ट्रिंग **। उदाहरण के लिए, हम यह कर सकते हैं:
function capitalizeFirstLetter([ first, ...rest ]) {
return [ first.toUpperCase(), ...rest ].join('');
}
capitalizeFirstLetter("𐐶𐐲𐑌𐐼𐐲𐑉") // "𐐎𐐲𐑌𐐼𐐲𐑉"
लंबे समय तक तार के लिए, यह शायद बहुत कुशल नहीं है *** - हमें वास्तव में शेष को पुनरावृत्त करने की आवश्यकता नहीं है। हम String.prototype.codePointAt
उस पहले (संभव) पत्र को प्राप्त करने के लिए उपयोग कर सकते हैं , लेकिन हमें अभी भी यह निर्धारित करने की आवश्यकता होगी कि स्लाइस कहां से शुरू होनी चाहिए। शेष के पुनरावृत्ति से बचने का एक तरीका यह परीक्षण करना होगा कि क्या पहला कोड बीएमपी के बाहर है; यदि ऐसा नहीं है, तो स्लाइस 1 से शुरू होता है, और यदि यह है, तो स्लाइस 2 से शुरू होता है।
function capitalizeFirstLetter(str) {
const firstCP = str.codePointAt(0);
const index = firstCP > 0xFFFF ? 2 : 1;
return String.fromCodePoint(firstCP).toUpperCase() + str.slice(index);
}
capitalizeFirstLetter("𐐶𐐲𐑌𐐼𐐲𐑉") // "𐐎𐐲𐑌𐐼𐐲𐑉"
आप > 0xFFFF
वहां के बजाय बिटवाइज़ गणित का उपयोग कर सकते हैं , लेकिन इस तरीके को समझना शायद आसान है और या तो एक ही चीज़ को प्राप्त करेगा।
यदि आवश्यक हो तो हम उस तर्क को थोड़ा आगे ले जाकर ES5 और नीचे में भी यह काम कर सकते हैं। कोडपॉइंट्स के साथ काम करने के लिए ES5 में कोई आंतरिक तरीके नहीं हैं, इसलिए हमें मैन्युअल रूप से परीक्षण करना होगा कि क्या पहली कोड यूनिट एक सरोगेट **** है:
function capitalizeFirstLetter(str) {
var firstCodeUnit = str[0];
if (firstCodeUnit < '\uD800' || firstCodeUnit > '\uDFFF') {
return str[0].toUpperCase() + str.slice(1);
}
return str.slice(0, 2).toUpperCase() + str.slice(2);
}
capitalizeFirstLetter("𐐶𐐲𐑌𐐼𐐲𐑉") // "𐐎𐐲𐑌𐐼𐐲𐑉"
शुरुआत में मैंने अंतर्राष्ट्रीयकरण के विचारों का भी उल्लेख किया। इनमें से कुछ के लिए हिसाब लगाना बहुत मुश्किल है क्योंकि उन्हें ज्ञान की आवश्यकता होती है न केवल किस भाषा का उपयोग किया जा रहा है, बल्कि भाषा में शब्दों के विशिष्ट ज्ञान की भी आवश्यकता हो सकती है। उदाहरण के लिए, आयरिश डाइग्राफ "एमबी" एक शब्द की शुरुआत में "एमबी" के रूप में कैपिटल करता है। एक और उदाहरण, जर्मन एसजेट, कभी भी एक शब्द (एफैक) शुरू नहीं करता है, लेकिन फिर भी समस्या को स्पष्ट करने में मदद करता है। लोअरकेस एज़ेट ("ß") "एसएस" को कैपिटल करता है, लेकिन "एसएस" या तो "s" या "एसएस" को कम कर सकता है - आपको यह जानने के लिए जर्मन भाषा के आउट-ऑफ-बैंड ज्ञान की आवश्यकता है जो सही है!
इस तरह के मुद्दों का सबसे प्रसिद्ध उदाहरण, शायद, तुर्की है। तुर्की लैटिन में, i का पूंजी रूप Latin है, जबकि I का निचला रूप ı है - वे दो अलग-अलग अक्षर हैं। सौभाग्य से हमारे पास इसके लिए एक तरीका है:
function capitalizeFirstLetter([ first, ...rest ], locale) {
return [ first.toLocaleUpperCase(locale), ...rest ].join('');
}
capitalizeFirstLetter("italy", "en") // "Italy"
capitalizeFirstLetter("italya", "tr") // "İtalya"
एक ब्राउज़र में, उपयोगकर्ता का सबसे पसंदीदा भाषा टैग द्वारा इंगित किया जाता है navigator.language
, वरीयता के क्रम में एक सूची मिलती है navigator.languages
, और दिए गए DOM तत्व की भाषा को Object(element.closest('[lang]')).lang || YOUR_DEFAULT_HERE
बहुभाषी दस्तावेजों के साथ (आमतौर पर) प्राप्त किया जा सकता है ।
RegExp में यूनिकोड संपत्ति चरित्र वर्गों का समर्थन करने वाले एजेंटों में, जो ES2018 में पेश किए गए थे, हम सीधे उन पात्रों को व्यक्त करके सामान को साफ कर सकते हैं जिनमें हम रुचि रखते हैं:
function capitalizeFirstLetter(str, locale=navigator.language) {
return str.replace(/^\p{CWU}/u, char => char.toLocaleUpperCase(locale));
}
यह काफी अच्छे सटीकता के साथ एक स्ट्रिंग में कई शब्दों को कैपिटलाइज़ करने के लिए थोड़ा सा भी ट्विक किया जा सकता है। CWU
या Changes_When_Uppercased चरित्र संपत्ति सब कोड अंक जो, ठीक है, परिवर्तन जब uppercased मेल खाता है। हम डच की तरह एक titlecased संयुक्ताक्षर पात्रों के साथ बाहर इस कोशिश कर सकते हैं ij उदाहरण के लिए:
capitalizeFirstLetter('ijsselmeer'); // "IJsselmeer"
लेखन के समय (फरवरी २०२०), फ़ायरफ़ॉक्स / स्पाइडरमोंकी ने अभी तक पिछले दो वर्षों में शुरू किए गए किसी भी RegExp फीचर को लागू नहीं किया है। आप इस सुविधा की वर्तमान स्थिति को कंगैक्स कम्पेटिटर टेबल पर देख सकते हैं । बैबेल RegExp शाब्दिक को उनके बिना समतुल्य पैटर्न के लिए संपत्ति संदर्भों के साथ संकलित करने में सक्षम है, लेकिन ध्यान रखें कि परिणामी कोड भारी हो सकता है।
सभी संभावना में, यह सवाल पूछने वाले लोगों का संबंध डेसेरिट कैपिटलाइज़ेशन या अंतर्राष्ट्रीयकरण से नहीं होगा। लेकिन इन मुद्दों के बारे में पता होना अच्छा है क्योंकि एक अच्छा मौका है कि आप अंततः उनका सामना करेंगे, भले ही वे वर्तमान में चिंता न करें। वे "एज" मामले नहीं हैं, या यों कहें, वे एज -डेफिनेशन एज के मामले नहीं हैं - एक पूरा देश है जहाँ ज्यादातर लोग तुर्की बोलते हैं, वैसे भी, और कोडपॉइंट्स के साथ कोड इकाइयाँ बनाना बग का एक बहुत ही सामान्य स्रोत है (विशेषकर के साथ) इमोजी के संबंध में)। तार और भाषा दोनों ही बहुत जटिल हैं!
* यूटीएफ -16 / यूसीएस 2 की कोड इकाइयाँ भी इस अर्थ में यूनिकोड कोड पॉइंट हैं, जैसे कि U + D800 तकनीकी रूप से एक कोड पॉइंट है, लेकिन इसका मतलब यह नहीं है कि "यहाँ" ... तरह का ... हालांकि यह सुंदर हो जाता है फजी। सरोगेट्स निश्चित रूप से नहीं हैं, हालांकि, यूएसवी (यूनिकोड स्केलर मान) है।
** हालांकि अगर एक सरोगेट कोड यूनिट "अनाथ" है - यानी, एक तार्किक जोड़ी का हिस्सा नहीं है - आप अभी भी यहां सरोगेट प्राप्त कर सकते हैं।
*** शायद। मैंने इसका परीक्षण नहीं किया है। जब तक आपने निर्धारित नहीं किया है कि कैपिटलाइज़ेशन एक सार्थक अड़चन है, मैं शायद इसे पसीना नहीं करूंगा - जो भी आप मानते हैं उसे चुनें जो सबसे अधिक स्पष्ट और पठनीय है।
**** इस तरह के एक समारोह में पहले के बजाय पहले और दूसरे दोनों कोड इकाइयों का परीक्षण करना चाह सकते हैं, क्योंकि यह संभव है कि पहली इकाई एक अनाथ सरोगेट है। उदाहरण के लिए इनपुट "\ uD800x" एक्स को कैपिटल करेगा, जो कि उम्मीद की जा सकती है या नहीं।
***** यदि आप प्रगति को और अधिक सीधे पालन करना चाहते हैं तो यह बुग्जिला मुद्दा है ।