হোয়াইটস্পেস ম্যাচিং রেজেক্স - জাভা


106

নিয়মিত এক্সপ্রেশনগুলির জন্য জাভা এপিআই বলছে যে \sসাদা স্থানের সাথে মিলবে। সুতরাং রেজেক্স \\s\\sদুটি স্পেসের সাথে মেলে।

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

এর লক্ষ্য হ'ল একক স্থানের সাথে টানা দুটি সাদা স্থানের সমস্ত দৃষ্টান্ত প্রতিস্থাপন করা। তবে এটি আসলে কাজ করে না।

আমার কি রেজেক্সেস বা "হোয়াইটস্পেস" শব্দটি সম্পর্কে গুরুতর ভুল বোঝাবুঝি হচ্ছে?


1
স্ট্রিংয়ের একটি প্রতিস্থাপন সমস্ত ফাংশন রয়েছে যা আপনাকে কয়েকটি লাইনের কোড সংরক্ষণ করবে save ডাউনলোড.
oracle.com/javase/1.5.0/docs/api/java/lang/String.html

1
এটি আপনার ভুল বোঝাবুঝি নয়, জাভা সম্পর্কিত। আমার অর্থটি "abc \xA0 def \x85 xyz"বোঝার মতো একটি স্ট্রিংকে বিভক্ত করার চেষ্টা করুন : সেখানে কেবল তিনটি ক্ষেত্র রয়েছে।
tchrist

3
আপনি কি "\\ s +" চেষ্টা করেছেন? এটির সাহায্যে আপনি দুটি বা ততোধিক স্পেস প্রতিস্থাপন করুন।
hrzafer

আমি এক ঘণ্টার বেশি সময় ধরে ভাবছিলাম যে কেন আমার স্প্লিট স্পেসে বিভক্ত হচ্ছে না। অসংখ্য ধন্যবাদ!
মার্সিন

উত্তর:


44

হ্যাঁ, আপনাকে এর ফলাফলটি ধরতে হবে matcher.replaceAll():

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

18
গাহ। আমি পৃথিবীর বৃহত্তম বোকা মনে হয়। আমি বা অন্য দুজনের কেউই তা খেয়াল করিনি বলে মনে হয়। আমার মনে হয় বোকা ছোট্ট ত্রুটিগুলি আমাদের মাঝে মাঝে ফেলে দেয়, তাই না?

আসলেই সত্য! আমার ধারণা তাদের মধ্যে এটিই সেরা
সাইবারথ

যদি লেখার শ্বেত স্পেস থাকে তবে আমার কী দরকার হবে?
গিলবার্তো ইবাররা

নীচের আমার উত্তর অনুসারে আপনি যদি ইউনিকোড হোয়াইটস্পেসের সাথে মেলে করতে চান তবে \ s এর পরিবর্তে \ p {Zs use ব্যবহার করুন।
রবার্ট

194

\sজাভা ইউনিকোড সাদা স্পেস সম্পত্তি সমর্থন করে না - যদিও জাভা ইউনিকোড # 18 এর আরএল 1.2 পূরণের জন্য কঠোরভাবে প্রয়োজন তবুও জাভা ইউনিকোড সাদা স্পেস সম্পত্তি সমর্থন করে না আপনি জাভাতে ব্যবহার করতে পারবেন না ! এটি যা আছে তা মানদণ্ড অনুসারে নয় a

ইউনিকোড 26 কোড পয়েন্টগুলি \p{White_Space}এমনভাবে সংজ্ঞায়িত করে : তাদের মধ্যে 20 \pZ জেনারাল ক্যাটাগরি = বিভাজক বিভিন্ন ধরণের এবং বাকী 6 টি \p{Cc} জেনারেল ক্যাটাগরি = নিয়ন্ত্রণ

হোয়াইট স্পেস একটি দুর্দান্ত স্থিতিশীল সম্পত্তি এবং সেই একই জিনিসগুলি প্রায় কার্যত চিরকাল। তবুও জাভাতে এমন কোনও সম্পত্তি নেই যা এর জন্য ইউনিকোড স্ট্যান্ডার্ডের সাথে সঙ্গতিপূর্ণ, সুতরাং আপনাকে পরিবর্তে এই জাতীয় কোড ব্যবহার করতে হবে:

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শেষ পর্যন্ত সঠিকভাবে আচরণ করতে আপনার কী করা উচিত !

হ্যাঁ, এটি সম্ভব, এবং হ্যাঁ, এটি একটি মাইন্ডবামিং গন্ডগোল। এমনকি দাতব্য হচ্ছে। জাভা জন্য একটি মান-অনুকরণকারী রেইগেক্স গ্রন্থাগার পাওয়ার সহজতম উপায় হ'ল জেএনআই থেকে আইসিইউয়ের স্টাফ to গুগল অ্যান্ড্রয়েডের জন্য এটিই করে, কারণ ওরাসুনের পরিমাপ হয় না।

আপনি যদি এটি না করতে চান তবে এখনও জাভা দিয়ে আটকে থাকতে চান তবে আমার একটি ফ্রন্ট-এন্ড রেজেক্স পুনর্লিখনের গ্রন্থাগার রয়েছে আমি লিখেছি যে "ফিক্স" জাভার ধরণগুলি অন্তত ইউটিএসে আরএল 1.2a এর প্রয়োজনীয়তা অনুসারে আনতে হবে # 18, ইউনিকোড নিয়মিত অভিব্যক্তি


12
জাভা এর রেগেক্স সীমাবদ্ধতা মাথা নেওয়ার জন্য ধন্যবাদ। +1
রজনার্নার

4
আমি এই উত্তরটি সহায়ক হিসাবে ভোট দিতে গিয়েছিলাম এবং আমার কাছে ইতিমধ্যে পাওয়া গেছে। সুতরাং দ্বিতীয়বার আপনাকে ধন্যবাদ :)
অ্যান্ড্রু ওয়াইল্ড

5
এটা সত্যিই পুরানো। এটি কি সঠিক যে এটি জাভা 7-এ ইউনিকোডE_CHARACTER_CLASS পতাকা সহ স্থির করা হয়েছিল? (বা ব্যবহার করে (? ইউ))
ক্রিটজিক্রতজি

5
@ ট্রিচ্রিস্ট যদি এটি জাভা 7+ এ স্থির করা হয় তবে আপনি কি উত্তরটি সঠিকভাবে সঠিকভাবে এটি আপডেট করতে পারবেন?
বেরবাজে

7
জাভা 7+ এর সাহায্যে আপনি এটি করতে পারেন: ইউনিকোড প্রযুক্তিগত স্ট্যান্ডার্ড কনফারেন্সের সাথে রেজেক্স চালানোর জন্য "(? ইউ)" s "। অথবা প্যাটার্নটি তৈরি করার সময় আপনি UNICODE_CHARACTER_CLASS পতাকাটি সত্য করতে পারেন। এখানে ডকটি রয়েছে: docs.oracle.com/javase/7/docs/api/java/util/regex/…
দিদিয়ার এ।

15

জাভার জন্য (পিএইচপি নয়, জাভাস্ক্রিপ্ট নয়, অন্য কোনও নয়):

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

স্ট্রিংগুলি পরিবর্তনযোগ্য নয়, সুতরাং আপনাকে ফলাফলটি এমন কোনও বিষয়কে নির্ধারণ করতে হবে, যেমন 'txt = txt.replaceAll ()' আমি আপনার উত্তরটি ভোট দিয়েছি না, তবে অন্য কেউ এর কারণ হতে পারে।
এনওয়াইড

6
আমি জানি যে প্রতিস্থাপনকৃত সমস্ত স্ট্রিং গুরুত্বপূর্ণ জিনিসটি 4 টি জাভা প্রগ্রেমারকে returns p {javaSpaceChar returns হিসাবে ফেরত দেয়
surfealokesea

2
মূল প্রশ্নটি ভেরিয়েবলের কাছে নতুন স্ট্রিংটি না দেওয়ার ভুল করেছে। ভুলটি উল্লেখ করা উত্তরের সবচেয়ে গুরুত্বপূর্ণ বিষয়।

এটি গ্রোভিতে আমার সমস্যার সম্পূর্ণ সমাধান করেছে! অবশেষে! প্রতিটি রেজেক্স চেষ্টা করে দেখতে পেলাম যে নন-BREAK-স্পেস (এএসসিআইআই 160) সহ সমস্ত সাদা জায়গার সাথে মিলবে!
পিকো

5

আমি যখন একটি প্রশ্ন একটি রেইগেক্সবাডি (রেজেক্স বিকাশকারী অ্যাপ্লিকেশন) ফোরামে প্রেরণ করেছি, তখন আমার জাভা প্রশ্নের আরও সঠিক উত্তর পেয়েছি:

"বার্তা লেখক: জান গোয়েভার্টস

জাভাতে, শর্টহ্যান্ডস, \ ডি এবং \ ডাব্লুগুলির মধ্যে কেবল এএসসিআইআই অক্ষর অন্তর্ভুক্ত রয়েছে। ... এটি জাভাতে কোনও বাগ নয়, তবে নিয়মিত প্রকাশের সাথে কাজ করার সময় আপনাকে যে সমস্ত বিষয় সম্পর্কে সচেতন হতে হবে কেবল তার মধ্যে একটি। সমস্ত ইউনিকোড সাদা স্থানের পাশাপাশি লাইন ব্রেকগুলির সাথে মিল রাখতে আপনি জাভাতে [in s \ p {Z}] ব্যবহার করতে পারেন use RegexBuddy এখনও জাভা-নির্দিষ্ট বৈশিষ্ট্য যেমন \ p {javaSpaceChar support (যা [\ s \ p {Z}] হিসাবে ঠিক একই অক্ষরের সাথে মেলে) সমর্থন করে না।

... the s AS 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

আর ই-তে হোয়াইটস্পেসের ব্যবহার ব্যথা হয় তবে আমি বিশ্বাস করি তারা কাজ করে। স্ট্রিংটোকেনাইজার বা বিভক্ত () পদ্ধতি ব্যবহার করে ওপির সমস্যাটিও সমাধান করা যায়। যাইহোক, ম্যাচার স্ট্রিংটি কীভাবে ভেঙে ফেলছে তা দেখতে আরআর (নিখুঁতভাবে প্রিন্টলন () ব্যবহার করতে এখানে একটি নমুনা কোড দেওয়া হল:

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) + "\"");
}}

এটি নিম্নলিখিতটি তৈরি করে (জাভ্যাকের সাথে সংকলন করে কমান্ড প্রম্পটে চালিত হবে):

% java two21WS প্রারম্ভিক: "ab cdef gh ij kl" two21WS: "ab cdef gh ij kl"


8
ডব্লিউটিএফ !? আপনি কেবল replaceAll()তার পরিবর্তে কল করতে পারলে আপনি কেন এটি করতে চান ?
অ্যালান মুর
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.