मैं C # में एकल स्थान के साथ कई स्थान कैसे बदलूं?


440

मैं C # में केवल एक स्थान के साथ एक स्ट्रिंग में कई रिक्त स्थान कैसे बदल सकता हूं?

उदाहरण:

1 2 3  4    5

होने वाला:

1 2 3 4 5

1
एक राज्य मशीन आसानी से कर सकती है, लेकिन यह संभवतः ओवरकिल है अगर आपको केवल रिक्त स्थान निकालने की आवश्यकता है
एड्रियन

मैंने डुप्लिकेट प्रश्न stackoverflow.com/a/37592018/582061 में ऐसा करने के विभिन्न तरीकों पर एक बेंचमार्क जोड़ा है । रेगेक्स ऐसा करने का सबसे तेज़ तरीका नहीं था।
स्टियन स्टैंडहल

जवाबों:


468
string sentence = "This is a sentence with multiple    spaces";
RegexOptions options = RegexOptions.None;
Regex regex = new Regex("[ ]{2,}", options);     
sentence = regex.Replace(sentence, " ");

2
मेरे पास कॉपी और पेस्ट है और यह काम करता है। मैं वास्तव में आरजेएक्स को पसंद नहीं करता हूं लेकिन इस बार यह मेरे जीवन को बचाता है।
पोकस

9
@ क्रेग एक टिप्पणी पर्याप्त होगा, IMO। // यह ब्लॉक एक साथ एक से अधिक रिक्त स्थान की जगह ... :)
paulwhit

6
वास्तव में, RegEx इसके लिए ओवरकिल है।
जोएल कोएहॉर्न

11
@Joel: सहमत नहीं हो सकते। मुझे वास्तव में यकीन है कि यह तरीका आपके लिए पर्याप्त रूप से बड़े स्ट्रिंग्स से अधिक कुशल है और इसे एक ही लाइन में किया जा सकता है। ओवरकिल कहां है?
कोनराड रुडोल्फ

24
@ ऑस्कर जोएल का कोड सभी पात्रों के माध्यम से एक सरल लूप नहीं है! यह एक छुपा हुआ नेस्टेड लूप है जिसमें एक द्विघात सबसे खराब स्थिति है। यह नियमित अभिव्यक्ति, इसके विपरीत, रैखिक है, केवल एक स्ट्रिंग (जोएल के कोड की तुलना में काफी कम आवंटन लागत) बनाता है) और इसके अलावा इंजन नरक से बाहर का अनुकूलन कर सकता है (ईमानदार होने के लिए, मुझे शक है। .NET regex इसके लिए पर्याप्त स्मार्ट लेकिन सिद्धांत रूप में इस नियमित अभिव्यक्ति को इतनी सस्ते में लागू किया जा सकता है कि यह और भी मज़ेदार नहीं है; इसे केवल तीन राज्यों के साथ डीएफए, प्रत्येक संक्रमण और कोई अतिरिक्त जानकारी नहीं चाहिए)।
कोनराड रुडोल्फ

624

मुझे उपयोग करना पसंद है:

myString = Regex.Replace(myString, @"\s+", " ");

चूंकि यह किसी भी तरह के व्हॉट्सएप (जैसे टैब, नईलाइन्स आदि) के रनों को पकड़ लेगा और उन्हें एक ही जगह से बदल देगा।


43
थोड़ा संशोधन: Regex.Replace (स्रोत, @ "(\ s) \ s +", "$ 1"); यह पाया गया पहला व्हाट्सएप प्रकार लौटाएगा। इसलिए यदि आपके पास 5 टैब हैं, तो यह एक टैब लौटाएगा। किसी को यह पसंद करते हैं।
एफबी दस केट

@radistao आपका लिंक जावास्क्रिप्ट स्ट्रिंग प्रतिस्थापित करने के लिए है, C # के लिए नहीं।
शिव

1
@ शिव, / \ s \ s + / एक मानक पॉज़िक्स रेगेक्स स्टेटमेंट है और इसे किसी भी भाषा में स्वयं सिंटैक्स का उपयोग करके परिवर्तित / उपयोग किया जा सकता है
radistao

4
@ FBtenKate के समाधान की भावना में: Regex.Replace (स्रोत, @ "(\ s) \ 1+", "$ 1"); एक के बाद एक कई समान लगातार वर्णों को प्रतिस्थापित करेगा ।
फ्रांस्वा

1
प्रमुख और अनुगामी व्हाट्सएप को हटाने के लिए आपको इसके साथ ट्रिम () फ़ंक्शन का उपयोग करना चाहिए, जैसे var myString = Regex.Replace (myString, @ "\ s +", "") .Trim ();
हरीश नायक

50
string xyz = "1   2   3   4   5";
xyz = string.Join( " ", xyz.Split( new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries ));

6
यह रेगेक्स पर अधिक पठनीय है, मैं इसे अधिक पसंद करता हूं क्योंकि मुझे कुछ अन्य वाक्यविन्यास सीखने की आवश्यकता नहीं है
माइकल बहिग

9
मुझे यह पसंद है क्योंकि इसे Regex
AleX_

3
यह बड़े तारों के लिए अक्षम होगा।
डार्सीटॉमस

3
यह भी अग्रणी और अनुगामी रिक्त स्थान को निकालता है।
Matzi

1
मैं इस उत्तर को भी पसंद करता हूं। मेरे पुराने गुरु कहते थे "कभी भी आपको कोई समस्या होती है जो आपको लगता है कि आपको हल करने के लिए रेगेक्स की जरूरत है, अच्छी तरह से ... अब आपको दो समस्याएं मिल गई हैं" <wink>
विलियम मैडोना जूनियर

38

मुझे लगता है कि मैट का जवाब सबसे अच्छा है, लेकिन मुझे विश्वास नहीं है कि यह काफी सही है। यदि आप नई लाइनों को बदलना चाहते हैं, तो आपको इसका उपयोग करना चाहिए:

myString = Regex.Replace(myString, @"\s+", " ", RegexOptions.Multiline);

4
RegexOptions.Multiline ^ और $ का अर्थ बदल जाता है इसलिए वे पूरे मल्टी-लाइन स्ट्रिंग के बजाय हर लाइन ($ = \ n) की शुरुआत और अंत से मेल खाते हैं। क्योंकि \ n [\ f \ n \ r \ t \ v] के बराबर है, भले ही मल्टीलाइन विकल्प बंद हो, नई कड़ियों को प्रतिस्थापित किया जाना चाहिए।
सुशीग्य

1
मैट के जवाब ने पहले ही इसे कवर कर लिया है। मुझे विश्वास है कि
'30

26

एक और दृष्टिकोण जो LINQ का उपयोग करता है:

 var list = str.Split(' ').Where(s => !string.IsNullOrWhiteSpace(s));
 str = string.Join(" ", list);

23

यह सब से बहुत सरल है:

while(str.Contains("  ")) str = str.Replace("  ", " ");

23
यह रेगेक्स "{2,}" की तुलना में बहुत कम कुशल होगा यदि स्ट्रिंग में 3 या अधिक रिक्त स्थान के अनुक्रम हैं।
जन गोयवर्ट्स

2
@JanGoyvaerts: 10 रिक्त स्थान के साथ भी, जब मैं एक त्वरित और गंदा परीक्षण करता था, तब रेगेक्स धीमा था। यह कहा जा रहा है, यह केवल लूप के प्रदर्शन को पूरी तरह से मारने के लिए रिक्त स्थान से भरा एक विशालकाय विकल्प लेता है। निष्पक्षता के लिए, मैंने धीमी Regex.Replace के बजाय RegexOptions.Compiled का उपयोग किया।
ब्रायन

5
RegexOptions.Compiled IL में regex संकलित ओवरहेड का एक बहुत कुछ जोड़ता है। इसका उपयोग तब तक न करें जब तक कि आपका एप्लिकेशन रेगेक्स का उपयोग अक्सर पर्याप्त या बड़े स्ट्रिंग्स पर नहीं करेगा, जो कि मिलान की हुई गति कम हो जाने वाली गति को बढ़ा देता है।
जनवरी गोयवर्ट्स

यह अत्यधिक अक्षम कोड का एक उदाहरण है। जबरदस्त हंसी।
पीसीबीबा

1
@ pcbabu यह उतना बुरा नहीं है जितना कि कई मामलों के लिए लगता है। Replace()विधि एक दिए गए स्ट्रिंग में दो रिक्त स्थान की सभी घटनाओं को संभाल लेंगे, तो हम नहीं पाशन रहे हैं (और एक पूरी स्ट्रिंग फिर से आवंटन) स्ट्रिंग में बनती रिक्त स्थान के हर उदाहरण के लिए। एक नया आवंटन उन सभी को संभाल लेगा। हम केवल लूप को फिर से चलाते हैं जब एक साथ 3 या अधिक रिक्त स्थान थे, जो कि कई इनपुट स्रोतों के लिए दुर्लभ घटना होने की संभावना है। यदि आप दिखा सकते हैं कि यह आपके डेटा के लिए एक समस्या बन गया है, तो चरित्र को एक नए स्ट्रिंगर में चरित्र को आगे बढ़ाने के लिए राज्य मशीन पर जाएं।
जोएल कोएहॉर्न

21

Regex को सरल कार्यों के साथ भी धीमा किया जा सकता है। यह एक विस्तार विधि बनाता है जिसे किसी भी उपयोग किया जा सकता है string

    public static class StringExtension
    {
        public static String ReduceWhitespace(this String value)
        {
            var newString = new StringBuilder();
            bool previousIsWhitespace = false;
            for (int i = 0; i < value.Length; i++)
            {
                if (Char.IsWhiteSpace(value[i]))
                {
                    if (previousIsWhitespace)
                    {
                        continue;
                    }

                    previousIsWhitespace = true;
                }
                else
                {
                    previousIsWhitespace = false;
                }

                newString.Append(value[i]);
            }

            return newString.ToString();
        }
    }

यह इस तरह के रूप में इस्तेमाल किया जाएगा:

string testValue = "This contains     too          much  whitespace."
testValue = testValue.ReduceWhitespace();
// testValue = "This contains too much whitespace."


11

उन लोगों के लिए, जो पसंद नहीं करते हैं Regex, यहां एक विधि है जो उपयोग करती है StringBuilder:

    public static string FilterWhiteSpaces(string input)
    {
        if (input == null)
            return string.Empty;

        StringBuilder stringBuilder = new StringBuilder(input.Length);
        for (int i = 0; i < input.Length; i++)
        {
            char c = input[i];
            if (i == 0 || c != ' ' || (c == ' ' && input[i - 1] != ' '))
                stringBuilder.Append(c);
        }
        return stringBuilder.ToString();
    }

मेरे परीक्षणों में, एक स्थिर संकलित रेगेक्स की तुलना में छोटे-से-मध्यम आकार के तारों के एक बहुत बड़े सेट के साथ यह विधि औसतन 16 गुना तेज थी। एक गैर-संकलित या गैर-स्थिर रेगेक्स की तुलना में, यह और भी तेज होना चाहिए।

ध्यान रखें, यह प्रमुख या अनुगामी रिक्त स्थान को नहीं हटाता है, केवल ऐसी कई घटनाएं होती हैं।


यदि आप जांचना चाहते हैं कि क्या चरित्र व्हाट्सएप है, और न केवल एक जगह नीचे मेरा जवाब देखें
रीप

8

आप बस एक लाइन समाधान में यह कर सकते हैं!

string s = "welcome to  london";
s.Replace(" ", "()").Replace(")(", "").Replace("()", " ");

आप चाहें तो अन्य कोष्ठक (या अन्य वर्ण भी) चुन सकते हैं।


1
आपको यह सुनिश्चित करना होगा कि आपके स्ट्रिंग में "()" या ") (" "नहीं है। या "wel()come to london)("बन जाता है "wel come to london"। आप कोष्ठक का उपयोग करने का प्रयास कर सकते हैं। इसलिए ((((()))))इसके बजाय ()और )))))(((((इसके बजाय का उपयोग करें )(। यह अभी भी काम करेगा। फिर भी, यदि स्ट्रिंग समाहित है ((((()))))या )))))(((((, यह विफल हो जाएगा।
nmit026

7

यह एक छोटा संस्करण है, जिसका उपयोग केवल तभी किया जाना चाहिए यदि आप केवल एक बार ऐसा कर रहे हैं, क्योंकि यह Regexहर बार कक्षा के एक नए उदाहरण को बनाता है जिसे इसे कहा जाता है।

temp = new Regex(" {2,}").Replace(temp, " "); 

यदि आप नियमित अभिव्यक्तियों से परिचित नहीं हैं, तो यहां एक संक्षिप्त विवरण दिया गया है:

यह {2,}पहले से मौजूद चरित्र के लिए रेगेक्स खोज करता है, और 2 और असीमित समय के बीच सबस्ट्रिंग पाता है।
.Replace(temp, " ")एक स्थान के साथ स्ट्रिंग अस्थायी में सभी मैचों बदल देता है।

यदि आप इसे कई बार उपयोग करना चाहते हैं, तो यहां एक बेहतर विकल्प है, क्योंकि यह संकलन समय पर regex IL बनाता है:

Regex singleSpacify = new Regex(" {2,}", RegexOptions.Compiled);
temp = singleSpacify.Replace(temp, " ");

7

कोई रेगेक्स, कोई लिनक ... प्रमुख और अनुगामी रिक्त स्थान को हटाता है और साथ ही एक अंतरिक्ष में कई एम्बेडेड स्पेस सेगमेंट को कम करता है

string myString = "   0 1 2  3   4               5  ";
myString = string.Join(" ", myString.Split(new char[] { ' ' }, 
StringSplitOptions.RemoveEmptyEntries));

परिणाम: "0 1 2 3 4 5"


1
सावधानी का एक शब्द: विभाजन का उपयोग, जबकि वास्तव में समझने के लिए बहुत सरल है, आश्चर्यजनक रूप से नकारात्मक प्रदर्शन प्रभाव हो सकता है। जितने भी तार पैदा किए जा सकते हैं, इस विधि से बड़े तार को संभालने की स्थिति में आपको अपना मेमोरी उपयोग देखना होगा।
Pac0

5

जोएल के अनुसार, और उम्मीद है कि जैसे ही मैं जाऊंगा, थोड़ा सुधार होगा:

आप इसके साथ कर सकते हैं Regex.Replace():

string s = Regex.Replace (
    "   1  2    4 5", 
    @"[ ]{2,}", 
    " "
    );

या साथ String.Split():

static class StringExtensions
{
    public static string Join(this IList<string> value, string separator)
    {
        return string.Join(separator, value.ToArray());
    }
}

//...

string s = "     1  2    4 5".Split (
    " ".ToCharArray(), 
    StringSplitOptions.RemoveEmptyEntries
    ).Join (" ");

3

मैंने अभी एक नया लिखा है Joinजो मुझे पसंद है, इसलिए मैंने सोचा कि मैं इसके साथ फिर से उत्तर दूंगा:

public static string Join<T>(this IEnumerable<T> source, string separator)
{
    return string.Join(separator, source.Select(e => e.ToString()).ToArray());
}

इसके बारे में ठंडी चीजों में से एक यह है कि यह उन संग्रह के साथ काम करता है जो तत्वों पर टॉसरिंग () को कॉल करके स्ट्रिंग्स नहीं हैं। उपयोग अभी भी समान है:

//...

string s = "     1  2    4 5".Split (
    " ".ToCharArray(), 
    StringSplitOptions.RemoveEmptyEntries
    ).Join (" ");

2
एक्सटेंशन पद्धति क्यों बनाएं? क्यों न केवल स्ट्रिंग का उपयोग करें। जॉइन ()?
एरिक शूनओवर 3

3
      // Mysample string
            string str ="hi you           are          a demo";

            //Split the words based on white sapce
            var demo= str .Split(' ').Where(s => !string.IsNullOrWhiteSpace(s));

            //Join the values back and add a single space in between
                    str = string.Join(" ", demo);

//output: string str ="hi you are a demo";

2

मुझे पता है कि यह बहुत पुराना है, लेकिन लगभग एक ही चीज को पूरा करने की कोशिश करते हुए इस पार भाग गया। RegEx बडी में यह समाधान मिला। यह पैटर्न सभी डबल स्पेस को सिंगल स्पेस से बदल देगा और लीडिंग और ट्रेलिंग स्पेस को भी ट्रिम कर देगा।

pattern: (?m:^ +| +$|( ){2,})
replacement: $1

खाली स्थान के साथ काम करने के बाद से इसे पढ़ना थोड़ा कठिन है, इसलिए यहाँ फिर से "रिक्त स्थान" के साथ एक "_" जगह है।

pattern: (?m:^_+|_+$|(_){2,})  <-- don't use this, just for illustration.

"(? M:") निर्माण "मल्टी-लाइन" विकल्प को सक्षम करता है। मैं आम तौर पर पैटर्न के भीतर जो भी विकल्प कर सकता हूं उसे शामिल करना पसंद करता हूं इसलिए यह अधिक आत्म निहित है।


2

कई उत्तर सही आउटपुट प्रदान कर रहे हैं, लेकिन सर्वश्रेष्ठ प्रदर्शन की तलाश करने वालों के लिए, मैंने नोलनार के उत्तर (जो प्रदर्शन के लिए सबसे अच्छा उत्तर था) में लगभग 10% सुधार किया ।

public static string MergeSpaces(this string str)
{

    if (str == null)
    {
        return null;
    }
    else
    {
        StringBuilder stringBuilder = new StringBuilder(str.Length);

        int i = 0;
        foreach (char c in str)
        {
            if (c != ' ' || i == 0 || str[i - 1] != ' ')
                stringBuilder.Append(c);
            i++;
        }
        return stringBuilder.ToString();
    }

}

1

मैं इसके साथ व्हॉट्सएप हटा सकता हूं

while word.contains("  ")  //double space
   word = word.Replace("  "," "); //replace double space by single space.
word = word.trim(); //to remove single whitespces from start & end.

हाँ, लेकिन आप केवल दो व्हाट्सएप को एक के साथ बदल देंगे। यह X के रिक्त स्थान की मदद नहीं करेगा
MGot90

1
जबकि लूप सभी को ध्यान रखेगा कि डबल स्पेस को हटाया जाए।
Learner1947

1

रेगेक्स पैटर्न का उपयोग करें

    [ ]+    #only space

   var text = Regex.Replace(inputString, @"[ ]+", " ");

1

इस विधि को आजमाएं

private string removeNestedWhitespaces(char[] st)
{
    StringBuilder sb = new StringBuilder();
    int indx = 0, length = st.Length;
    while (indx < length)
    {
        sb.Append(st[indx]);
        indx++;
        while (indx < length && st[indx] == ' ')
            indx++;
        if(sb.Length > 1  && sb[0] != ' ')
            sb.Append(' ');
    }
    return sb.ToString();
}

इसे इस तरह उपयोग करें:

string test = removeNestedWhitespaces("1 2 3  4    5".toCharArray());

यह ट्रेलिंग स्पेस को हटा देगा
The_Black_Smurf

गलती के लिए खेद है, मैंने कोड तय किया, अब यह अपेक्षित परीक्षण स्ट्रिंग के रूप में काम कर रहा है: "1 2 3 4 9" परिणाम स्ट्रिंग: "1 2 3 4 9"
अहमद अलजफ

1

यहाँ Nolonar मूल उत्तर पर एक मामूली संशोधन किया गया है ।

यह जाँचना कि क्या चरित्र केवल एक स्थान नहीं है, लेकिन किसी भी व्हाट्सएप का उपयोग करें:

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

public static string FilterWhiteSpaces(string input)
{
    if (input == null)
        return string.Empty;

    var stringBuilder = new StringBuilder(input.Length);
    for (int i = 0; i < input.Length; i++)
    {
        char c = input[i];
        if (i == 0 || !char.IsWhiteSpace(c) || (char.IsWhiteSpace(c) && 
            !char.IsWhiteSpace(strValue[i - 1])))
            stringBuilder.Append(c);
    }
    return stringBuilder.ToString();
}

0

पुराना विद्यालय:

string oldText = "   1 2  3   4    5     ";
string newText = oldText
                    .Replace("  ", " " + (char)22 )
                    .Replace( (char)22 + " ", "" )
                    .Replace( (char)22 + "", "" );

Assert.That( newText, Is.EqualTo( " 1 2 3 4 5 " ) );

0

नियमित अभिव्यक्ति का उपयोग किए बिना:

while (myString.IndexOf("  ", StringComparison.CurrentCulture) != -1)
{
    myString = myString.Replace("  ", " ");
}

शॉर्ट स्ट्रिंग्स पर उपयोग करने के लिए ठीक है, लेकिन बहुत सारे रिक्त स्थान के साथ लंबे स्ट्रिंग्स पर खराब प्रदर्शन करेगा।


0

स्ट्रिंग के लिए स्ट्रांगबर्ल और एन्युमरेबल। एग्रीगेट () के रूप में विस्तार विधि का मिश्रण :

using System;
using System.Linq;
using System.Text;

public static class StringExtension
{
    public static string StripSpaces(this string s)
    {
        return s.Aggregate(new StringBuilder(), (acc, c) =>
        {
            if (c != ' ' || acc.Length > 0 && acc[acc.Length-1] != ' ')
                acc.Append(c);

            return acc;
        }).ToString();
    }

    public static void Main()
    {
        Console.WriteLine("\"" + StringExtension.StripSpaces("1   Hello       World  2   ") + "\"");
    }
}

इनपुट:

"1   Hello       World  2   "

आउटपुट:

"1 Hello World 2 "
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.