2013-01-23 45 views
10

पर समान नहीं हैं। मैं दो जावा स्ट्रिंग्स की तुलना करने के लिए एक तरीका ढूंढ रहा हूं जो लेक्सिकोग्राफिक रूप से समकक्ष हैं लेकिन बाइट स्तर पर समान नहीं हैं।दो स्ट्रिंग्स की तुलना करें जो लेक्सिकोग्राफिक रूप से समकक्ष हैं लेकिन बाइट स्तर

अधिक स्पष्ट निम्न फ़ाइल नाम "baaaé.png", बाइट स्तर यह दो अलग अलग तरीकों दर्शाया जा सकता है पर ले:,

[98, 97, 97, 97, -61 -87 , 46, 112, 110, 103] -> "é" 2 बाइट्स के साथ इनकोडिंग

[98, 97, 97, 97, 101, -52, -127, 46, 112, 110, 103] -> "é" को 3 बाइट

byte[] ch = {98, 97, 97, 97, -61, -87, 46, 112, 110, 103}; 
    byte[] ff = {98, 97, 97, 97, 101, -52, -127, 46, 112, 110, 103}; 

    String st = new String(ch,"UTF-8"); 
    String st2 = new String(ff,"UTF-8"); 
    System.out.println(st); 
    System.out.println(st2); 
    System.out.println(st.equals(st2)); 

के साथ एन्कोड किया गया है निम्नलिखित आउटपुट उत्पन्न करेगा:

baaaé.png 
baaaé.png 
false 

तुलना करने का कोई तरीका है ताकि बराबर विधि सही हो जाए?

+5

वे इसे यहां प्रस्तुत नहीं करते हैं। –

+3

@dystroy जो हमें "_lexicographically equal_" कथन पर पुनर्विचार करने की ओर ले जाता है :) – Fallup

+3

@dystroy वेब के लिए (दृढ़ता से) पसंदीदा सामान्यीकृत फॉर्म एनएफसी है। स्पष्ट रूप से आपका वेब ब्राउज़र आसान शॉर्टकट लेता है और केवल एनएफसी का समर्थन करता है, न कि एनएफडी। इसके लायक होने के लिए, मेरा वही करता है। स्पष्ट रूप से वेब ब्राउज़र एनएफडी लागू करने से परेशान नहीं हैं। हालांकि, मैं दोनों उदाहरणों को एक अलग एप्लिकेशन में कॉपी और पेस्ट कर सकता हूं जो एनएफसी और एनएफडी दोनों का समर्थन करता है और वे समान रूप से प्रदर्शित होते हैं। – Celada

उत्तर

8

आप Collator कक्षा का उपयोग विभिन्न उच्चारण अंकों जैसी चीज़ों को सामान्य करने के लिए लागू शक्ति के साथ कर सकते हैं। यह आपको तारों की सफलतापूर्वक तुलना करने की अनुमति देगा।

इस मामले में, एक अमेरिका स्थान और एक तृतीयक शक्ति बराबर होना तार करने के लिए पर्याप्त है

Collator usCollator = Collator.getInstance(); 
usCollator.setStrength(Collator.TERTIARY); 
System.out.println(usCollator.equals(st, st2)); 

आउटपुट

true 

तुम भी जावा के Normalizer वर्ग का उपयोग कर सकते अलग के बीच परिवर्तित करने के लिए यूनिकोड के रूप। यह आपके तारों को बदल देगा, लेकिन वे समान होने के साथ-साथ मानक स्ट्रिंग टूल्स का उपयोग करने की इजाजत दे सकते हैं, तुलना करने के लिए

अंत में, ICU (यूनिकोड के लिए अंतर्राष्ट्रीय घटक) प्रोजेक्ट को देखना चाहें, जो कई अलग-अलग तरीकों से यूनिकोड तारों के साथ काम करने के लिए बहुत सारे टूल प्रदान करता है।

+0

मैंने Normalizer वर्ग का परीक्षण किया है और यह पूरी तरह से काम करता है। धन्यवाद। – Davz

7

है कि आप इस पर गौर करने की जरूरत है Unicode normalization forms दो प्रकार के होते हैं:

वहाँ पहले एक एनएफसी बनाम NFD है। आपके प्रश्न में जो उदाहरण दिया गया है वह एनएफसी और एनएफडी के बीच अलग-अलग का एक उत्कृष्ट उदाहरण है। आपकी पहली स्ट्रिंग एनएफसी में है जबकि आपका दूसरा एनएफडी में है।

यूनिकोड में, कई उच्चारण वर्णों को दो अलग-अलग तरीकों से प्रदर्शित किया जा सकता है: मूल चरित्र के बाद संयोजन संयोजन, या एक पूर्ववर्ती उच्चारण वाले चरित्र के रूप में। जब क्षेत्र उपलब्ध होता है तो एनएफसी प्रीकॉम्ज्ड वर्णों का उपयोग करता है। एनएफडी हमेशा विघटित रूपों का उपयोग करता है।

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

जावा Normalizer नामक एक निर्मित कक्षा प्रदान करता है जो एक स्ट्रिंग को किसी दिए गए यूनिकोड रूप में परिवर्तित कर सकता है।

2 अन्य सामान्यीकृत रूप मौजूद हैं: एनएफकेसी और एनएफकेडी। ये रूप सामान्य उपयोग के लिए नहीं हैं, बल्कि केवल शब्दावली तुलना के लिए हैं। वे इस तथ्य के लिए जिम्मेदार हैं कि, उदाहरण के लिए, ¼ को खोज या तुलना में 1/4 के समान माना जाना चाहिए। लेकिन वे यह नहीं दर्शाते कि ¼ और 1/4 समान हैं या जिन्हें आम तौर पर दूसरे में परिवर्तित किया जाना चाहिए।

एनएफसी से एनएफकेसी और एनएफडी से एनएफकेडी तक रूपांतरण फिर से सीधा है (आपको चरित्र डेटाबेस की आवश्यकता है) लेकिन इस बार यह हानिकारक है। आपको मूल एनएफसी/एनएफडी टेक्स्ट रखना होगा और केवल एक खोज/सॉर्ट कुंजी के रूप में एनएफकेसी/एनएफकेडी का उपयोग करना होगा।

+0

जावा [Normalizer] (http://docs.oracle.com/javase/6/docs/api/java/text/Normalizer.html) नामक एक निर्मित कक्षा प्रदान करता है जो एक स्ट्रिंग को किसी दिए गए यूनिकोड फ़ॉर्म –

+0

+ में परिवर्तित कर सकता है + 1 आपके विस्तृत उत्तर के लिए जो समस्या के मूल कारण को स्पष्ट रूप से बताता है। – Davz