व्हॉट्सएप मैचिंग रेगेक्स - जावा


106

नियमित अभिव्यक्तियों के लिए जावा एपीआई बताता है कि \sव्हाट्सएप से मेल खाएगा। तो रेगेक्स \\s\\sको दो स्थानों से मेल खाना चाहिए।

Pattern whitespace = Pattern.compile("\\s\\s");
matcher = whitespace.matcher(modLine);
while (matcher.find()) matcher.replaceAll(" ");

इसका उद्देश्य दो लगातार व्हाट्सएप के सभी उदाहरणों को एक ही स्थान से बदलना है। हालाँकि यह वास्तव में काम नहीं करता है।

क्या मुझे रीगेक्स की गंभीर गलतफहमी है या "व्हॉट्सएप" शब्द?


1
स्ट्रिंग में एक प्रतिस्थापन कार्य होता है जो आपको कोड की कुछ पंक्तियों को बचाएगा। download.oracle.com/javase/1.5.0/docs/api/java/lang/String.html
ज़ैक एल

1
यह आपकी गलतफहमी नहीं है, लेकिन जावा की है। एक स्ट्रिंग को विभाजित करने की कोशिश करें जैसे "abc \xA0 def \x85 xyz"कि मेरा क्या मतलब है: वहां केवल तीन क्षेत्र हैं।
tchrist

3
क्या आपने "\\ s +" की कोशिश की। इसके साथ आप दो या दो से अधिक स्पेस को एक में बदलते हैं।
रोजज़र

मैं एक घंटे से अधिक समय से सोच रहा हूं कि क्यों मेरा \\ का विभाजन व्हॉट्सएप पर नहीं बंट रहा है। बहुत - बहुत धन्यवाद!
मार्सिन

जवाबों:


44

हाँ, आपको इसका परिणाम प्राप्त करने की आवश्यकता है matcher.replaceAll():

String result = matcher.replaceAll(" ");
System.out.println(result);

18
गाह। मुझे पृथ्वी पर सबसे बड़ा बेवकूफ लगता है। न तो मुझे और न ही दो अन्य लोगों को नोटिस किया गया था। मुझे लगता है कि मूर्खतापूर्ण छोटी त्रुटियां हमें कभी-कभी दूर कर देती हैं, एह?

सच है! मुझे लगता है कि उनमें से सबसे अच्छा के साथ होता है
साईबरनाथ

यदि पाठ को व्हाइट स्पेस मिले तो मुझे क्या होगा?
गिल्बर्टो इबारा

यदि आप यूनिकोड व्हाट्सएप से मिलान करना चाहते हैं, तो नीचे दिए गए मेरे जवाब के अनुसार, \ _ {Zs} का उपयोग करें।
रॉबर्ट

194

आप \sजावा में अपने स्वयं के मूल चरित्र सेट पर सफेद स्थान का मिलान करने के लिए उपयोग नहीं कर सकते हैं , क्योंकि जावा यूनिकोड सफेद अंतरिक्ष संपत्ति का समर्थन नहीं करता है - भले ही ऐसा करने के लिए यूटीएस # 18 के आरएल 1.2 को पूरा करने की सख्त आवश्यकता है ! इसके पास जो है वह मानकों के अनुरूप नहीं है, अफसोस।

यूनिकोड 26 कोड बिंदुओं को परिभाषित करता है \p{White_Space}: उनमें से 20 विभिन्न प्रकार के \pZ GeneralCategory = विभाजक हैं , और शेष 6 \p{Cc} GeneralCategory = Control हैं

श्वेत स्थान एक बहुत ही स्थिर संपत्ति है, और वे लगभग हमेशा के लिए रहे हैं। फिर भी, जावा के पास ऐसी कोई संपत्ति नहीं है जो इन के लिए यूनिकोड मानक के अनुरूप हो, इसलिए आपको इसके बजाय कोड का उपयोग करना होगा:

String whitespace_chars =  ""       /* dummy empty string for homogeneity */
                        + "\\u0009" // CHARACTER TABULATION
                        + "\\u000A" // LINE FEED (LF)
                        + "\\u000B" // LINE TABULATION
                        + "\\u000C" // FORM FEED (FF)
                        + "\\u000D" // CARRIAGE RETURN (CR)
                        + "\\u0020" // SPACE
                        + "\\u0085" // NEXT LINE (NEL) 
                        + "\\u00A0" // NO-BREAK SPACE
                        + "\\u1680" // OGHAM SPACE MARK
                        + "\\u180E" // MONGOLIAN VOWEL SEPARATOR
                        + "\\u2000" // EN QUAD 
                        + "\\u2001" // EM QUAD 
                        + "\\u2002" // EN SPACE
                        + "\\u2003" // EM SPACE
                        + "\\u2004" // THREE-PER-EM SPACE
                        + "\\u2005" // FOUR-PER-EM SPACE
                        + "\\u2006" // SIX-PER-EM SPACE
                        + "\\u2007" // FIGURE SPACE
                        + "\\u2008" // PUNCTUATION SPACE
                        + "\\u2009" // THIN SPACE
                        + "\\u200A" // HAIR SPACE
                        + "\\u2028" // LINE SEPARATOR
                        + "\\u2029" // PARAGRAPH SEPARATOR
                        + "\\u202F" // NARROW NO-BREAK SPACE
                        + "\\u205F" // MEDIUM MATHEMATICAL SPACE
                        + "\\u3000" // IDEOGRAPHIC SPACE
                        ;        
/* A \s that actually works for Java’s native character set: Unicode */
String     whitespace_charclass = "["  + whitespace_chars + "]";    
/* A \S that actually works for  Java’s native character set: Unicode */
String not_whitespace_charclass = "[^" + whitespace_chars + "]";

अब आप whitespace_charclass + "+"अपने पैटर्न के रूप में उपयोग कर सकते हैं replaceAll


सॉरी 'बाउट दैट ऑल। जावा के रेगेक्स अपने मूल चरित्र सेट पर बहुत अच्छी तरह से काम नहीं करते हैं, और इसलिए आपको वास्तव में उन्हें काम करने के लिए विदेशी हुप्स के माध्यम से कूदना होगा।

और अगर आपको लगता है कि सफेद स्थान खराब है, तो आपको यह देखना चाहिए कि आपको प्राप्त करने के लिए क्या करना है \wऔर \bअंत में ठीक से व्यवहार करना है!

हाँ, यह संभव है, और हाँ, यह एक नासमझ गड़बड़ है। वह धर्मार्थ भी हो रहा है। जावा के लिए एक मानक-अनुकूल रिजेक्स लाइब्रेरी पाने का सबसे आसान तरीका आईसीएन के सामान पर जेएनआई है। यह वही है जो Google Android के लिए करता है, क्योंकि OraSun की माप नहीं होती है।

यदि आप ऐसा नहीं करना चाहते हैं, लेकिन फिर भी जावा के साथ रहना चाहते हैं, तो मेरे पास एक फ्रंट-रेगेक्स रि-राइटिंग लाइब्रेरी है, जिसमें मैंने लिखा है कि जावा के पैटर्न को ठीक करता है, कम से कम उन्हें यूटीएस में RL1.2a की आवश्यकताओं के अनुरूप पाने के लिए। # 18, यूनिकोड रेगुलर एक्सप्रेशंस


12
जावा की रेगेक्स सीमाओं पर सिर के लिए धन्यवाद। +1
राइडरुननर

4
मैं इस उत्तर को मददगार के रूप में वोट करने गया और पाया कि मेरे पास पहले से ही था। तो दूसरी बार धन्यवाद :)
एंड्रयू व्याल

5
यह वास्तव में पुराना है। क्या यह सही है कि यह UNICODE_CHARACTER_CLASS ध्वज के साथ java7 में तय किया गया था? (या उपयोग (? यू))
kritzikratzi

5
@tchrist अगर यह जावा 7+ में तय किया गया है, तो क्या आप ऐसा करने के लिए अब-सही तरीके से जवाब अपडेट कर सकते हैं?
बीयरबजाय

7
जावा 7+ के साथ आप कर सकते हैं: यूनिकोड तकनीकी मानक अनुरूपता के साथ regex को चलाने के लिए "(? यू) \"। या आप पैटर्न बनाते समय UNICODE_CHARACTER_CLASS ध्वज को सच कर सकते हैं। यहाँ डॉक्टर: docs.oracle.com/javase/7/docs/api/java/util/regex/…
डिडिएर ए।

15

जावा के लिए (php नहीं, जावास्क्रिप्ट नहीं, कोई भी अभिभावक नहीं):

txt.replaceAll("\\p{javaSpaceChar}{2,}"," ")

स्ट्रिंग्स अपरिवर्तनीय हैं, इस प्रकार आपको परिणाम को कुछ पर असाइन करना होगा, जैसे कि 'txt = txt.replaceAll ()' मैंने आपके उत्तर को वोट नहीं दिया, लेकिन हो सकता है कि किसी और ने ऐसा किया हो।
एनवायर्ड किया गया

6
मुझे पता है कि सभी लोग एक स्ट्रिंग को एक महत्वपूर्ण चीज देते हैं 4 जावा प्रोग्रामर \\ p {javaSpaceChar} है
17

2
मूल प्रश्न ने नई स्ट्रिंग को एक चर में निर्दिष्ट नहीं करने की गलती की। इंगित करना कि गलती इस प्रकार उत्तर का सबसे महत्वपूर्ण बिंदु है।
एनवक्त

इसने ग्रूवी में मेरी समस्या को पूरी तरह हल कर दिया! आखिरकार! मुझे लगता है कि NON-BREAK-SPACE (ASCII 160) सहित सभी सफेद स्थान से मेल खाती है कि हर regex की कोशिश कर रहा हूँ !!!
पिको

5

जब मैंने Regexbuddy (regex developer application) फोरम में एक प्रश्न भेजा, तो मुझे अपने \ _ जावा सवाल का अधिक सटीक उत्तर मिला:

"संदेश लेखक: जन गोयवर्ट्स

जावा में, शॉर्टहैंड्स \ _, डी, और \ w में केवल ASCII वर्ण शामिल हैं। ... यह जावा में एक बग नहीं है, लेकिन बस कई चीजों में से एक है जिसे आपको नियमित अभिव्यक्ति के साथ काम करते समय जागरूक होना चाहिए। सभी यूनिकोड व्हाट्सएप के साथ-साथ लाइन ब्रेक से मिलान करने के लिए, आप जावा में [\ s \ p {Z}] का उपयोग कर सकते हैं। RegexBuddy अभी तक जावा-विशिष्ट गुणों जैसे \ p {javaSpaceChar} का समर्थन नहीं करता है (जो [\ s \ p {Z}] के समान सटीक वर्णों से मेल खाता है)।

... \ 's \ s दो रिक्त स्थान से मेल खाएगा, यदि इनपुट केवल ASCII है। वास्तविक समस्या ओपी के कोड के साथ है, जैसा कि उस प्रश्न में स्वीकृत उत्तर द्वारा इंगित किया गया है। "


3
[\s\p{z}]यूनिकोड "अगली पंक्ति" वर्ण U + 0085 को छोड़ता है। का उपयोग करें [\s\u0085\p{Z}]
रॉबर्ट तुपेलो-श्नेक

3

लगता है मेरे लिए काम करता है:

String s = "  a   b      c";
System.out.println("\""  + s.replaceAll("\\s\\s", " ") + "\"");

प्रिंट होगा:

" a  b   c"

मुझे लगता है कि आप अपने कोड के बजाय ऐसा करने का इरादा रखते हैं:

Pattern whitespace = Pattern.compile("\\s\\s");
Matcher matcher = whitespace.matcher(s);
String result = "";
if (matcher.find()) {
    result = matcher.replaceAll(" ");
}

System.out.println(result);

3

अपने उद्देश्य के लिए आप इस स्निपेट का उपयोग कर सकते हैं:

import org.apache.commons.lang3.StringUtils;

StringUtils.normalizeSpace(string);

यह स्पेसिंग को सिंगल कर देगा और स्टार्टिंग और ट्रेलिंग व्हाट्सएप को भी बंद कर देगा।

String sampleString = "Hello    world!";
sampleString.replaceAll("\\s{2}", " "); // replaces exactly two consecutive spaces
sampleString.replaceAll("\\s{2,}", " "); // replaces two or more consecutive white spaces

1
Pattern whitespace = Pattern.compile("\\s\\s");
matcher = whitespace.matcher(modLine);

boolean flag = true;
while(flag)
{
 //Update your original search text with the result of the replace
 modLine = matcher.replaceAll(" ");
 //reset matcher to look at this "new" text
 matcher = whitespace.matcher(modLine);
 //search again ... and if no match , set flag to false to exit, else run again
 if(!matcher.find())
 {
 flag = false;
 }
}

3
माइक, जबकि मैं आपको जवाब देने के लिए समय देने की सराहना करता हूं, यह सवाल कई महीने पहले हल किया गया है। इस के रूप में पुराने के रूप में सवालों का जवाब देने की जरूरत नहीं है।

6
यदि कोई अलग, बेहतर समाधान दिखा सकता है, तो पुराने प्रश्नों का उत्तर देना पूरी तरह से वैध है।
james.garriss

1

इस मुद्दे को पहली बार सामने लाने के बाद जावा विकसित हुआ है। आप \p{Zs}समूह का उपयोग करके सभी प्रकार के यूनिकोड अंतरिक्ष वर्णों का मिलान कर सकते हैं ।

इस प्रकार यदि आप एक या अधिक विदेशी स्थानों को एक सादे स्थान के साथ बदलना चाहते हैं, तो आप ऐसा कर सकते हैं:

String txt = "whatever my string is";
txt.replaceAll("\\p{Zs}+", " ")

यह जानने के लायक भी है कि, यदि आपने trim()स्ट्रिंग फंक्शन का उपयोग किया है तो आपको (अपेक्षाकृत नया) पर एक नज़र डालनी चाहिए strip(),stripLeading() और stripTrailing()तारों पर काम करता है। सभी प्रकार के सफेद अंतरिक्ष वर्णों को छाँटने में आपकी सहायता कर सकता है। किस स्थान को शामिल किया गया है, इस बारे में अधिक जानकारी के लिए, जावा का Character.isWhitespace()कार्य देखें।


-3

आरई में व्हाट्सएप का उपयोग एक दर्द है, लेकिन मेरा मानना ​​है कि वे काम करते हैं। OP की समस्या को StringTokenizer या स्प्लिट () विधि का उपयोग करके भी हल किया जा सकता है। हालाँकि, आरईई (प्रिंटनल को अनलॉन्च करने के लिए) (यह देखने के लिए कि मिलान स्ट्रिंग को कैसे तोड़ रहा है) का उपयोग करने के लिए, यहां एक नमूना कोड दिया गया है:

import java.util.regex.*;

public class Two21WS {
    private String  str = "";
    private Pattern pattern = Pattern.compile ("\\s{2,}");  // multiple spaces

    public Two21WS (String s) {
            StringBuffer sb = new StringBuffer();
            Matcher matcher = pattern.matcher (s);
            int startNext = 0;
            while (matcher.find (startNext)) {
                    if (startNext == 0)
                            sb.append (s.substring (0, matcher.start()));
                    else
                            sb.append (s.substring (startNext, matcher.start()));
                    sb.append (" ");
                    startNext = matcher.end();
                    //System.out.println ("Start, end = " + matcher.start()+", "+matcher.end() +
                    //                      ", sb: \"" + sb.toString() + "\"");
            }
            sb.append (s.substring (startNext));
            str = sb.toString();
    }

    public String toString () {
            return str;
    }

    public static void main (String[] args) {
            String tester = " a    b      cdef     gh  ij   kl";
            System.out.println ("Initial: \"" + tester + "\"");
            System.out.println ("Two21WS: \"" + new Two21WS(tester) + "\"");
}}

यह निम्नलिखित उत्पन्न करता है (javac के साथ संकलन और कमांड प्रॉम्प्ट पर चलता है):

% java Two21WS आरंभिक: "ab cdef gh ij kl" Two21WS: "ab cdef gh ij kl"


8
WTF !? आप वह सब क्यों करना चाहेंगे, जब आप replaceAll()इसके बजाय सिर्फ कॉल कर सकते हैं ?
एलन मूर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.