2008-09-29 10 views
21

अधिक सटीक होने के लिए, मुझे यह जानने की ज़रूरत है कि (और यदि संभव हो, कैसे) मैं यह पा सकता हूं कि किसी दिए गए स्ट्रिंग में डबल बाइट वर्ण हैं या नहीं । असल में, मुझे किसी दिए गए टेक्स्ट को प्रदर्शित करने के लिए पॉप-अप खोलना होगा जिसमें चीनी या जापानी जैसे डबल बाइट वर्ण हो सकते हैं। इस मामले में, हमें अंग्रेजी या ASCII के मुकाबले खिड़की के आकार को समायोजित करने की आवश्यकता है। किसी के पास कोई सुराग है?यह पता लगाने के लिए कि किसी विशेष स्ट्रिंग में यूनिकोड वर्ण हैं (esp। डबल बाइट वर्ण)

+0

अच्छा, मुझे यह काम करने की उम्मीद थी। लेकिन यह आईई में काम नहीं किया। मुझे लगता है कि कुछ लेआउट समस्याएं हैं। वैसे भी, चूंकि पाठ को टेक्स्ट-टू-लू-लम्बाई लंबाई और ऊंचाई/चौड़ाई की गणना करने के लिए कोड पहले से ही था, इसलिए मैं उस कोड के साथ आगे बढ़ गया जो सिर्फ एक डबल बाइट चरित्र है या नहीं। और यह हल हो गया। – Jay

+0

एचटीएमएल 5 के साथ, आप चौड़ाई पाठ मीट्रिक प्राप्त करने के लिए कैनवास तत्व ('var ctx = canvas.getContext ('2d')') के संदर्भ का उपयोग कर सकते हैं। 'var text_width = ctx.measureText (text) .width; 'मुझे यकीन नहीं है कि यह विधि यूनिकोड वर्णों के साथ कितनी अच्छी तरह से काम करती है, और यह एक शर्म की बात है कि वर्तमान में सभी' माप टेक्स्ट 'विधि चौड़ाई है। – WebWanderer

उत्तर

25

जावास्क्रिप्ट आंतरिक रूप से यूसीएस -2 के रूप में पाठ रखता है, जो यूनिकोड के काफी व्यापक सबसेट को एन्कोड कर सकता है।

लेकिन यह वास्तव में आपके प्रश्न के लिए जर्मन नहीं है। एक समाधान स्ट्रिंग लूप करने के लिए हो सकता है और प्रत्येक स्थिति में चरित्र कोड की पड़ताल करनी चाहिए:

function isDoubleByte(str) { 
    for (var i = 0, n = str.length; i < n; i++) { 
     if (str.charCodeAt(i) > 255) { return true; } 
    } 
    return false; 
} 

यह जितनी जल्दी आप चाहते हैं के रूप में नहीं हो सकता है।

+0

मुझे जावास्क्रिप्ट नहीं पता है, लेकिन क्या आपका मतलब यूटीएफ -16 नहीं है? यूसीएस -16 जैसी कोई चीज नहीं है; आईसीएस-एक्स एन्कोडिंग फॉर्म थे, अब अप्रचलित, आईएसओ/आईईसी 10646 मानक में जो यूनिकोड के बराबर है। यूसीएस -2 ने वास्तव में दो बाइट्स का इस्तेमाल किया और इस प्रकार पहले 2^16 यूनिकोड वर्णों का प्रतिनिधित्व कर सकता था। यूटीएफ -16, इसके विपरीत, 16-बिट इकाइयों का उपयोग करता है, लेकिन जरूरी नहीं कि उनमें से एक भी। सभी यूनिकोड वर्णों को यूटीएफ -16 बाइट अनुक्रमों के रूप में प्रदर्शित किया जा सकता है। –

+0

मेरा मानना ​​है कि आपका मतलब यूसीएस -2 है। –

+1

मेरा मतलब यूसीएस -2 था, धन्यवाद। – pcorcoran

0

क्यों रनटाइम ऊंचाई/चौड़ाई के आधार पर खिड़की का आकार बदलना नहीं है? इस तरह

भागो कुछ अपने पॉप-अप में:

window.resizeTo(document.body.clientWidth, document.body.clientHeight); 
+0

ऐसा कुछ गैर-रोगजनक मामलों में काम करना चाहिए; बेशक आपको यह सुनिश्चित करना होगा कि आप उपलब्ध स्क्रीन स्पेस से अधिक नहीं हैं, या कम से कम उचित सीमाएं मानें। – JasonTrue

6

वास्तव में, पात्रों के सभी यूनिकोड, कम से कम जावास्क्रिप्ट इंजन के नजरिए से कर रहे हैं।

दुर्भाग्य से, किसी विशेष यूनिकोड रेंज में वर्णों की केवल उपस्थिति यह निर्धारित करने के लिए पर्याप्त नहीं होगी कि आपको अधिक जगह चाहिए। ऐसे कई पात्र हैं जो मोटे तौर पर समान मात्रा में स्थान लेते हैं जैसे कि अन्य वर्ण जिनके पास यूनिकोड कोडपॉइंट्स ASCII रेंज से ऊपर हैं। टाइपोग्राफिक उद्धरण, विशिष्टता वाले वर्ण, कुछ विराम चिह्न प्रतीकों, और विभिन्न मुद्रा प्रतीकों कम ASCII रेंज के बाहर हैं और यूनिकोड मूल बहुभाषी विमान पर काफी अलग स्थानों में आवंटित किए जाते हैं।

आम तौर पर, जिन परियोजनाओं पर मैंने सभी भाषाओं के लिए अतिरिक्त स्थान प्रदान करने के लिए चुना है, या कभी-कभी जावास्क्रिप्ट का उपयोग यह निर्धारित करने के लिए किया जाता है कि ऑटो-स्क्रॉलबार सीएसएस विशेषता वाले विंडो में वास्तव में ऊंचाई के साथ सामग्री है जो स्क्रॉलबार को ट्रिगर करेगी या नहीं । [\ u3300- \ u9fff \ uf900- \:

हैं की उपस्थिति, या की, CJK वर्ण गिनती का पता लगाने का निर्धारण करने के अतिरिक्त स्थान का एक सा की जरूरत है पर्याप्त हो जाएगा, आप निम्नलिखित सीमा का उपयोग कर एक regex का निर्माण कर सकता है ufaff], और मिलान करने वाले पात्रों की संख्या की गिनती निकालने के लिए इसका उपयोग करें। (यह थोड़ा अधिक मोटा है, और सभी गैर-बीएमपी मामलों को याद करता है, शायद कुछ अन्य प्रासंगिक श्रेणियों को छोड़ देता है, और अधिकतर कुछ अप्रासंगिक पात्र शामिल हैं, लेकिन यह एक प्रारंभिक बिंदु है)।

फिर से, आप केवल एक पूर्ण टेक्स्ट रेंडरिंग इंजन की लाइनों के साथ किसी न किसी तरह के किसी न किसी हर्मीस्टिक को प्रबंधित करने में सक्षम होने जा रहे हैं, क्योंकि आप जो वास्तव में चाहते हैं वह जीडीआई के मेजरस्ट्रिंग (या किसी अन्य टेक्स्ट रेंडरिंग इंजन के बराबर) जैसा कुछ है। । थोड़ा समय के बाद से मैं ऐसा करने के बाद किया गया है, लेकिन मुझे लगता है कि सबसे करीब HTML/डोम बराबर एक div पर एक चौड़ाई की स्थापना और ऊंचाई अनुरोध कर रहा है (कट और पेस्ट का पुन: उपयोग, इसलिए क्षमा याचना अगर यह त्रुटियाँ हैं):

o = document.getElementById("test"); 

document.defaultView.getComputedStyle(o,"").getPropertyValue("height")) 
23

मैंने इस पर mikesamuel जवाब का उपयोग किया। हालांकि मैंने शायद इस रूप के कारण देखा कि u से पहले केवल एक बच निकलना चाहिए, उदाहरण के लिए इस काम को सही तरीके से करने के लिए \u और \\u नहीं।मेरे लिए

function containsNonLatinCodepoints(s) { 
    return /[^\u0000-\u00ff]/.test(s); 
} 

वर्क्स :)

+0

आपका फ़ंक्शन चुने हुए उत्तर से काफी बेहतर है, रेगेक्स हमेशा बेहतर होता है – AmerllicA

1

मैं शीर्ष जवाब में दो कार्य बेंचमार्क और सोचा था कि मैं परिणामों को साझा करेंगे है।

const text1 = `The Chinese Wikipedia was established along with 12 other Wikipedias in May 2001. 中文維基百科的副標題是「海納百川,有容乃大」,這是中国的清朝政治家林则徐(1785年-1850年)於1839年為`; 

const regex = /[^\u0000-\u00ff]/; // Small performance gain from pre-compiling the regex 
function containsNonLatinCodepoints(s) { 
    return regex.test(s); 
} 

function isDoubleByte(str) { 
    for (var i = 0, n = str.length; i < n; i++) { 
     if (str.charCodeAt(i) > 255) { return true; } 
    } 
    return false; 
} 

function benchmark(fn, str) { 
    let startTime = new Date(); 
    for (let i = 0; i < 10000000; i++) { 
     fn(str); 
    } 
    let endTime = new Date(); 

    return endTime.getTime() - startTime.getTime(); 
} 

console.info('isDoubleByte => ' + benchmark(isDoubleByte, text1)); 
console.info('containsNonLatinCodepoints => ' + benchmark(containsNonLatinCodepoints, text1)); 

जब यह मुझे मिल चल:: यहाँ परीक्षण कोड मैं प्रयोग किया जाता है

isDoubleByte => 2421 
containsNonLatinCodepoints => 868 

तो इस विशेष स्ट्रिंग के लिए रेगुलर एक्सप्रेशन से समाधान के बारे में 3 गुना तेजी से है।

हालांकि ध्यान दें कि एक स्ट्रिंग के लिए जहां पहला अक्षर यूनिकोड है, isDoubleByte() तुरंत रिटर्न करता है और इसलिए रेगेक्स (जो अभी भी नियमित अभिव्यक्ति का ओवरहेड है) से बहुत तेज़ है।

स्ट्रिंग 中国 के लिए उदाहरण के लिए, मैं इन परिणामों मिला:

isDoubleByte => 51 
containsNonLatinCodepoints => 288 

दोनों दुनिया का सबसे अच्छा पाने के लिए, यह शायद दोनों गठबंधन करने के लिए बेहतर है:

var regex = /[^\u0000-\u00ff]/; // Small performance gain from pre-compiling the regex 
function containsDoubleByte(str) { 
    if (!str.length) return false; 
    if (str.charCodeAt(0) > 255) return true; 
    return regex.test(str); 
} 

उस मामले में, अगर पहला चरित्र चीनी है (जो संभव है कि पूरा पाठ चीनी है), फ़ंक्शन तेज़ होगा और तुरंत वापस आ जाएगा। यदि नहीं, तो यह रेगेक्स चलाएगा, जो प्रत्येक चरित्र को व्यक्तिगत रूप से जांचने से अभी भी तेज़ है।

संबंधित मुद्दे