2009-06-29 9 views
28

पार्स किए गए एचटीएमएल से गैर-ब्रेकिंग स्पेस को ट्रिम करने के लिए एक उचित तरीका खोजने के दौरान, मैंने पहली बार String.trim() की जावा की स्पार्टन परिभाषा पर ठोकर खाई है जो कम से कम सही तरीके से प्रलेखित है। मैं स्पष्ट रूप से ट्रिमिंग के पात्र पात्रों को सूचीबद्ध करना चाहता था, इसलिए मैंने माना कि कैरेक्टर क्लास पर यूनिकोड समर्थित विधियों का उपयोग करना मेरे लिए काम करेगा।गैर-ब्रेकिंग स्पेस जावा में एक सफेद जगह नहीं है?

जब मुझे पता चला कि Character.isWhitespace(char) स्पष्ट रूप से गैर तोड़ने रिक्त स्थान शामिल नहीं है यही कारण है कि:

यह एक यूनिकोड अंतरिक्ष चरित्र (SPACE_SEPARATOR, LINE_SEPARATOR, या PARAGRAPH_SEPARATOR) है लेकिन यह भी एक नॉन-ब्रेकिंग स्पेस नहीं है ('\u00A0' , '\u2007', '\u202F')।

वह क्यों है?

corresponding .NET equivalent का कार्यान्वयन कम भेदभावपूर्ण है।

उत्तर

20

Character.isWhitespace(char) पुराना है। वास्तव में पुराना। जावा के शुरुआती दिनों में किए गए कई कामों ने सी

से सम्मेलन और कार्यान्वयन का पालन किया, अब एक दशक बाद, ये चीजें गलत लगती हैं। इस बात पर विचार करें कि जावा के पहले दिनों और .NET के पहले दिनों के बीच भी चीजें कितनी दूर आई हैं।

जावा 100% पिछड़ा संगत होने का प्रयास करता है। तो अगर जावा टीम ने सोचा कि उनकी शुरुआती गलती को ठीक करना अच्छा होगा और अक्षरों के सेट पर गैर-ब्रेकिंग रिक्त स्थान जोड़ें जो Character.isWhitespace (char) से सच है, वे नहीं कर सकते हैं, क्योंकि लगभग निश्चित रूप से सॉफ़्टवेयर मौजूद है वर्तमान कार्यान्वयन पर निर्भर करता है जिस तरह से यह काम करता है।

+3

पिछड़े संगतता के संबंध में: मैं सहमत हूं, लेकिन कोई कारण नहीं है कि वर्तमान स्थिति को कैप्चर करने के लिए Character.isWhitespaceNew (char) को जोड़ने, कहने का कोई कारण नहीं है। – Jirka

+13

नीचे वह सड़क PHP है। – Eric

+7

और दूसरी सड़क के नीचे, ठीक है, जावा। एक ऐसी भाषा जिसने पीछा किया था (जो इसकी गलतियों से सीखा) के लिए निशान को उजागर किया, लेकिन अगर कोई अन्य विकल्प मेरे समझ से परे है तो स्वेच्छा से इसका इस्तेमाल क्यों करेंगे। – Eloff

2

ऐसा लगता है कि विधि का नाम (isWhitespace) अपने कार्य (विभाजक का पता लगाने के लिए) के साथ असंगत है। "विभाजक" कार्यक्षमता काफी स्पष्ट है अगर आप जावाडोक पेज आप उद्धृत से पात्रों की पूरी सूची पर नज़र डालें:

* It is a Unicode space character (SPACE_SEPARATOR, LINE_SEPARATOR, or PARAGRAPH_SEPARATOR) but is not also a non-breaking space ('\u00A0', '\u2007', '\u202F'). 
* It is '\u0009', HORIZONTAL TABULATION. 
* It is '\u000A', LINE FEED. 
* It is '\u000B', VERTICAL TABULATION. 
* It is '\u000C', FORM FEED. 
* It is '\u000D', CARRIAGE RETURN. 
* It is '\u001C', FILE SEPARATOR. 
* It is '\u001D', GROUP SEPARATOR. 
* It is '\u001E', RECORD SEPARATOR. 
* It is '\u001F', UNIT SEPARATOR. 

एक नॉन-ब्रेकिंग स्पेस के समारोह शब्द है कि द्वारा अलग नहीं है के बीच दृश्य अंतरिक्ष माना जाता है हाइफेनेशन एल्गोरिदम।

7

मैं तर्क दूंगा कि जावा का कार्यान्वयन .NET की तुलना में अधिक सही है। गैर-ब्रेकिंग स्पेस अनिवार्य रूप से एक गैर-सफेद जगह है जो एक जैसा दिखता है। यही है, अगर आपके पास "foo" और "bar" तार हैं, और उनके बीच कोई पारंपरिक सफेद जगह चरित्र डालते हैं, तो आपको एक शब्द ब्रेक मिल जाएगा। हालांकि, एक गैर-ब्रेकिंग स्पेस दो को तोड़ नहीं देता है।

+4

एक गैर-ब्रेकिंग स्पेस अभी भी एक शब्द सीमा है। "गैर-ब्रेकिंग स्पेस" में "ब्रेकिंग" का अर्थ यह है कि इसे ** लाइन ** के उद्देश्यों के लिए कैसे व्याख्या किया जाना चाहिए - ब्रेकिंग, शब्द ब्रेक नहीं। – richardtallent

6

एक बार गैर-ब्रेकिंग स्पेस का इलाज किया जाना चाहिए, विशेष रूप से कोड के शब्द-लपेटने के लिए डिज़ाइन किए गए कोड के साथ।

शब्द सीमाओं के साथ शब्द गणना, ट्रिमिंग और सामान्य उद्देश्य के विभाजन के साथ अन्य सभी उद्देश्यों के लिए, एक गैर-ब्रेकिंग स्पेस अभी भी व्हाइटस्पेस है।

कोई भी तर्क जो एक गैर-ब्रेकिंग स्पेस केवल एक जगह जैसा दिखता है लेकिन यूनिकोड के पूरे बिंदु के साथ एक संघर्ष नहीं है, जो कि उनके अर्थ के आधार पर वर्णों का प्रतिनिधित्व करता है, न कि उन्हें कैसे प्रदर्शित किया जाता है।

इस प्रकार, आईएमएचओ, स्ट्रिंग.ट्रिम() का जावा कार्यान्वयन अपेक्षित प्रदर्शन नहीं कर रहा है, और अंतर्निहित कैरेक्टर.इस व्हाइटसाइट() फ़ंक्शन गलती है।

मेरा अनुमान है कि जावा कार्यान्वयनकर्ताओं ने नियंत्रण में टेक्स्ट-रैपिंग करने की आवश्यकता के आधार पर व्हाइटस्पेस() लिखा है। उन्हें इस समारोह का नाम होना चाहिए था WordWrappingBoundary() या कुछ और स्पष्ट, और ट्रिम() के लिए एक कम-प्रतिबंधित व्हाइटस्पेस परीक्षण का उपयोग किया जाना चाहिए था।

+5

String.trim() इससे भी अधिक टूटा हुआ है। यह सिर्फ ASCII नियंत्रण वर्णों को ट्रिम करता है, और कोई यूनिकोड व्हाइटस्पेस बिल्कुल नहीं तोड़ता है या नहीं। – Thilo

13

जावा 5 के बाद से isSpaceChar(int) विधि भी है। क्या वह नहीं करता जो आप चाहते हैं?

निर्धारित करता है कि निर्दिष्ट वर्ण (यूनिकोड कोड पॉइंट) एक यूनिकोड स्पेस कैरेक्टर है या नहीं। एक चरित्र को एक स्पेस कैरेक्टर माना जाता है यदि केवल और यदि इसे यूनिकोड मानक द्वारा स्पेस कैरेक्टर के रूप में निर्दिष्ट किया गया हो। इस विधि सच रिटर्न अगर चरित्र की सामान्य श्रेणी प्रकार निम्न में से कोई है: ...

+1

यह इस तरह की एक विधि का अस्तित्व नहीं है जिसे ओपी ढूंढ रहा था; बल्कि एक 'ट्रिम' प्रकार का फ़ंक्शन जो * उस पद्धति का उपयोग करता है यह निर्धारित करने के लिए कि क्या स्ट्रिप करना है। –

+0

ध्यान दें कि 'isSpaceChar (char)' विधि –

+0

है ISpaceChar() विधि में लैटिन व्हाइट स्पेस (उदाहरण के लिए टैब) शामिल नहीं है। – zendu

10

जैसा कि ऊपर पोस्ट, isSpaceChar(int) जवाब देने के लिए एक ट्रैक के साथ ओपी प्रदान करेगा। ऐसा लगता है कि यह काफी बुद्धिमानी से प्रलेखित है, लेकिन यह विधि वास्तव में useable with regexes है। तो:

"X\u00A0X X".replaceAll("\\p{javaSpaceChar}", "_"); 

एक "X_X_X" स्ट्रिंग का उत्पादन करेगा। यह एक स्ट्रिंग को ट्रिम करने के लिए रीडर के साथ आने के लिए पाठक के लिए एक अभ्यास के रूप में छोड़ दिया जाता है। (कुछ झंडे के साथ पैटर्न चाल करना चाहिए।)

+0

काम करता है, अतिरिक्त "->" एक्स \ u00A0XX ".replaceAll (" \\ p {javaSpaceChar} "," _ ")); – user85155

+0

\ p {javaSpaceChar} कहीं भी प्रलेखित नहीं प्रतीत होता है। – zendu

+1

@zendu - यह है, यद्यपि बहुत स्पष्ट रूप से नहीं: 1) https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html#jcc: > जावा की तरह व्यवहार करने वाली श्रेणियां। lang.Character बूलियन ismethodname विधियों (बहिष्कृत लोगों को छोड़कर) एक ही \ p {prop} वाक्यविन्यास के माध्यम से उपलब्ध हैं जहां निर्दिष्ट संपत्ति का नाम javamethodname है। 2) https://docs.oracle.com/javase/7 /docs/api/java/lang/Character.html#isSpaceChar(char) –

2

भी सतर्क जब Apache Commons समारोह StringUtils.isBlank() (और संबंधित कार्यों) जो यानी एक नॉन-ब्रेकिंग स्पेस गैर माना जाता है एक ही अजीब isWhitespace व्यवहार, है का उपयोग किया खाली।

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