স্ট্রিং থেকে সমস্ত সাদা স্থান সরানোর কার্যকর উপায়?


358

আমি একটি REST এপিআই কল করছি এবং একটি এক্সএমএল প্রতিক্রিয়া ফিরে পাচ্ছি। এটি একটি কর্মক্ষেত্রের নামের তালিকা দেয় এবং আমি একটি দ্রুত IsExistingWorkspace()পদ্ধতি লিখছি writing যেহেতু সমস্ত কর্মক্ষেত্র কোনও শ্বেত স্পেসবিহীন স্বচ্ছ অক্ষরের সমন্বয়যুক্ত, তাই আমি কোনও নির্দিষ্ট কর্মক্ষেত্রের তালিকায় রয়েছে কিনা তা সন্ধান করার সবচেয়ে সহজ উপায়টি ধরে নিচ্ছি যে সমস্ত শ্বেত স্পেস (নতুনলাইন সহ) সরিয়ে ফেলা এবং এটি করা (এক্সএমএল ওয়েব থেকে প্রাপ্ত স্ট্রিং) অনুরোধ করুন):

XML.Contains("<name>" + workspaceName + "</name>");

আমি জানি এটি কেস-সংবেদনশীল এবং আমি তার উপর নির্ভর করছি। স্ট্রিংয়ের দক্ষতার সাথে সমস্ত সাদা স্থান সরানোর জন্য আমার কেবল একটি উপায় দরকার। আমি জানি রেজিএক্স এবং লিনকিউ এটি করতে পারে তবে আমি অন্যান্য ধারণার জন্য উন্মুক্ত। আমি বেশিরভাগ ক্ষেত্রে কেবল গতি সম্পর্কে উদ্বিগ্ন।


6
রেগেক্সের সাথে এক্সএমএল পার্স করা রেগেক্সের সাথে এইচটিএমএল পার্স করার মতো প্রায় খারাপ ।
dtb

3
@ হেনক হোল্টারম্যান; নীচে আমার উত্তরটি দেখুন, রেজিএক্সপ্যাক সব ক্ষেত্রে দ্রুততম বলে মনে হচ্ছে না।
হেনক জে মিউলেক্যাম্প

রেজেক্স মোটেও দ্রুত বলে মনে হচ্ছে না। আমি স্ট্রিং থেকে সাদা স্থান অপসারণ করার বিভিন্ন উপায় থেকে ফলাফলগুলির সংক্ষিপ্তসার করেছি। - সারাংশ নীচে একটি উত্তর হয় stackoverflow.com/a/37347881/582061
Stian Standahl

উত্তর:


616

এটি আমার পক্ষে দ্রুততম উপায়, যদিও আপনি বলেছিলেন যে আপনি নিয়মিত অভিব্যক্তিটি ব্যবহার করতে চান না:

Regex.Replace(XML, @"\s+", "")

1
আমি একটি নিয়মিত এক্সপ্রেশন ব্যবহার করতে পারতাম, আমি এটির দ্রুততম উপায় কিনা তা সম্পর্কে নিশ্চিত নই।
কোরি ওগবার্ন

1
আমি নিশ্চিত এটি। পর্দার অন্ততপক্ষে আপনাকে প্রতিটি চরিত্র পরীক্ষা করতে হবে এবং এটি কেবল একটি লিনিয়ার অনুসন্ধান করছে doing
অপবাদ

19
তা কি হওয়া উচিত নয় Regex.Replace(XML, @"\s+", "")?
জানু-পিটার ভোস

61
আপনি যদি একাধিকবার এটি করার পরিকল্পনা করেন তবে একটি রেজেক্স উদাহরণ তৈরি এবং সংরক্ষণ করুন। এটি প্রতিবার এটি নির্মাণের ওভারহেড সংরক্ষণ করবে, যা আপনি ভাবেন তার চেয়ে বেশি ব্যয়বহুল। private static readonly Regex sWhitespace = new Regex(@"\s+"); public static string ReplaceWhitespace(string input, string replacement) { return sWhitespace.Replace(input, replacement); }
হাইপিউম্যান

10
RegEx- এ নতুন যারা এবং এই অভিব্যক্তিটির অর্থ কী তা বোঝার জন্য অনুসন্ধানের অর্থ, \s"কোনও সাদা +অংশের টোকেনের সাথে মিলে যায়" এবং এর অর্থ "এগিয়ে চলার টোকেনের এক বা একাধিক ম্যাচ"। এছাড়াও RegExr সঙ্গে Regex এক্সপ্রেশন লেখার যদি আপনি পরীক্ষা করতে চান অনুশীলন করতে একটা চমৎকার ওয়েব সাইট।
জুন

181

আমার কাছে রেজিপক্স ছাড়া একটি বিকল্প উপায় আছে এবং এটি বেশ ভাল পরিবেশিত করছে বলে মনে হচ্ছে। এটি ব্র্যান্ডন মোরেটজ উত্তরের একটি ধারাবাহিকতা:

 public static string RemoveWhitespace(this string input)
 {
    return new string(input.ToCharArray()
        .Where(c => !Char.IsWhiteSpace(c))
        .ToArray());
 }

আমি এটি একটি সাধারণ ইউনিট পরীক্ষায় পরীক্ষা করেছি:

[Test]
[TestCase("123 123 1adc \n 222", "1231231adc222")]
public void RemoveWhiteSpace1(string input, string expected)
{
    string s = null;
    for (int i = 0; i < 1000000; i++)
    {
        s = input.RemoveWhitespace();
    }
    Assert.AreEqual(expected, s);
}

[Test]
[TestCase("123 123 1adc \n 222", "1231231adc222")]
public void RemoveWhiteSpace2(string input, string expected)
{
    string s = null;
    for (int i = 0; i < 1000000; i++)
    {
        s = Regex.Replace(input, @"\s+", "");
    }
    Assert.AreEqual(expected, s);
}

১,০০,০০০ চেষ্টা করে প্রথম বিকল্পটি (রিজেক্সপ ছাড়াই) কম পরে চালিত হয় দ্বিতীয় (আমার মেশিনে 700 এমএস), এবং দ্বিতীয়টি 3.5 সেকেন্ড সময় নেয়।


40
.ToCharArray()প্রয়োজন হয় না; আপনি .Where()সরাসরি একটি স্ট্রিং ব্যবহার করতে পারেন ।
প্রোগ্রামফক্স

10
শুধু এখানে লক্ষণীয়। রেজেক্স ধীরে ধীরে ... ছোট স্ট্রিংগুলিতে! আপনি যদি বলেন যে মুষ্টিমেয় পুনরাবৃত্তি সহ ইউএস ট্যাক্স আইন (~ মিলিয়ন ডলার?) এর একটি ভলিউমের একটি ডিজিটাইজড সংস্করণ আপনার কাছে রয়েছে, তবে খুব সহজেই রিজেক্স রাজা! এটি দ্রুত যা তা নয়, তবে কোন পরিস্থিতিতে কোনটি ব্যবহার করা উচিত। আপনি এখানে অর্ধেক সমীকরণ প্রমাণ করেছেন। -1 আপনি পরীক্ষার দ্বিতীয়ার্ধ প্রমাণ না হওয়া পর্যন্ত উত্তর কখন কী ব্যবহার করা উচিত তার আরও অন্তর্দৃষ্টি দেয়।
পাইওটার কুলা

17
@ পিপমকিন তিনি হোয়াইটস্পেসের একক পাস অপসারণের জন্য বলেছিলেন। অন্যান্য প্রক্রিয়াকরণের একাধিক পুনরাবৃত্তি নয়। আমি এই একক পাসের সাদা বাক্সটি সরানোর জন্য বেনমার্কিং পাঠ্য প্রক্রিয়াকরণ সম্পর্কে একটি বর্ধিত পোস্টে আনতে যাচ্ছি না।
হেনক জে মুলেক্যাম্প

1
আপনি বলেছিলেন যে এটি পুনরায় রেজেক্সের জন্য ব্যবহার না করা পছন্দ হয়েছে তবে কেন তা বলেন নি।
পাইওটর কুলা

2
@ প্রোগ্রামআফক্স, একটি অন্য প্রশ্নে (সহজেই এটি খুঁজে পাচ্ছে না) আমি লক্ষ্য করেছি যে কমপক্ষে কিছু প্রশ্নের ক্ষেত্রে স্ট্রিংয়ের উপরে সরাসরি ToCharArrayব্যবহার .Where()করার চেয়ে ব্যবহার করা আরও দ্রুত । এটি IEnumerable<>প্রতিটি পুনরাবৃত্তির ধাপে ওভারহেডের সাথে কিছু করার আছে এবং ToCharArrayখুব দক্ষ (ব্লক-অনুলিপি) হওয়া এবং সংকলক অ্যারেতে পুনরাবৃত্তিকে অনুকূল করে। কেন এই পার্থক্য বিদ্যমান, কেউই আমাকে ব্যাখ্যা করতে সক্ষম হয় নি, তবে আপনি অপসারণের আগে পরিমাপ করুন ToCharArray()
আবেল

87

সি # তে স্ট্রিংয়ের প্রতিস্থাপন পদ্ধতিটি ব্যবহার করে দেখুন।

XML.Replace(" ", string.Empty);

28
ট্যাব বা নিউলাইনগুলি সরিয়ে দেয় না। আমি যদি এখন একাধিক সরান করি তবে আমি স্ট্রিংয়ের উপরে একাধিক পাস করছি making
কোরি ওগবার্ন

11
সমস্ত গ্লো স্পেস অপসারণ না করার জন্য ডাউনভোট যেমনটি অপবাদ এবং হেনকের উত্তর দেয়।
ম্যাট শ্যাচ

@ ম্যাটস্যাচ কেন এটি সমস্ত সাদা স্থান সরিয়ে দেয় না?
জাপানোলজিকা

4
@ জাপানোলজিকা এটি কেবল স্থান অক্ষরের পরিবর্তে cing ওপি নতুন লাইনের প্রতিস্থাপনের জন্যও অনুরোধ করেছিল (যা "স্পেসস্পেস" অক্ষর, যদিও তারা কোনও স্থানের অক্ষর না হলেও)।
ম্যাট শ্যাচ

75

আমার সমাধানটি স্প্লিট এবং যোগদান ব্যবহার করা এবং এটি আশ্চর্যজনকভাবে দ্রুত, আসলে এখানে শীর্ষস্থানীয় উত্তরগুলির মধ্যে দ্রুততম।

str = string.Join("", str.Split(default(string[]), StringSplitOptions.RemoveEmptyEntries));

নতুন স্ট্র্যাপে নতুন লাইন এবং ট্যাবগুলি সহ সহজ স্ট্রিংয়ে 10,000 লুপের সময়

  • বিভাজন / যোগদান = 60 মিলিসেকেন্ড
  • লিনাক চররে = 94 মিলিসেকেন্ড
  • regex = 437 মিলিসেকেন্ড

এটির অর্থ দেওয়ার জন্য পদ্ধতিতে এটিকে মোড়ানো দ্বারা এটি উন্নত করুন, এবং আমরা যখন থাকি তখন এটি একটি এক্সটেনশন পদ্ধতিও করে তোলে ...

public static string RemoveWhitespace(this string str) {
    return string.Join("", str.Split(default(string[]), StringSplitOptions.RemoveEmptyEntries));
}

3
আমি এই সমাধানটি সত্যিই পছন্দ করি, প্রাক-লিনকিউ দিন থেকেই আমি একই জাতীয় ব্যবহার করছি। আমি লিনকুইসের পারফরম্যান্সে আসলেই মুগ্ধ হয়েছি এবং রেজেক্সের সাথে কিছুটা অবাক হয়েছি। কোডটি রিজেক্সের জন্য যেমন হতে পারত ততটা অনুকূল ছিল না (উদাহরণস্বরূপ আপনাকে রেজেক্স অবজেক্টটি ক্যাশে করতে হবে)। তবে সমস্যার ঘাটতিটি হ'ল ডেটাটির "মানের" অনেকটাই গুরুত্বপূর্ণ। সম্ভবত দীর্ঘ স্ট্রিং সহ রেজেক্স অন্যান্য বিকল্পগুলিকে ছাড়িয়ে যাবে। এটি সম্পাদন করা একটি মজাদার বেঞ্চমার্ক হবে ... :-)
লডেনভিয়ার

1
কীভাবে ডিফল্ট (স্ট্রিং []) == সমস্ত সাদা স্থানের অক্ষরের একটি তালিকা রয়েছে? আমি এটি কাজ করে দেখছি, তবে বুঝতে পারছি না কীভাবে?
জ্যাক ড্র

5
@ কার্নোকোড বলতে কী বোঝায় যে 2 ওভারলোডের সাথে string[]এবং এর মধ্যে অস্পষ্টতা char[]? আপনি কেবল একটি নির্দিষ্ট করতে হবে যেমন: উদাহরণস্বরূপ string.Join("", str.Split((string[])null, StringSplitOptions.RemoveEmptyEntries));। আপনার কলটি defaultএই ক্ষেত্রে যেটি করতে হবে সেহেতু এটি একই সাথে ফিরে আসে null: এটি কোনও ওভারলোড বাছাই করার সিদ্ধান্ত নিতে সংকলকটিকে সহায়তা করে। সুতরাং আমার মন্তব্য কারণ আপনার মন্তব্যে "বিভক্তির জন্য একটি বৈধ অ্যারের প্রয়োজন এবং নাল করবে না ..." মিথ্যা statement কোনও বড় বিষয় নয়, জ্যাক ড্রুকে জিজ্ঞাসা করা হয়েছে যে এটি কীভাবে কাজ করে। আপনার উত্তরের জন্য +1
ফ্র্যাঙ্ক জে

6
দুর্দান্ত ধারণা ... তবে আমি এটি নিম্নলিখিত হিসাবে করব:string.Concat("H \ne llo Wor ld".Split())
মাইক্রেলক্রিপার

3
মাইক্রক্রিস্পার দ্রবণটি খুব পঠনযোগ্য। আমি একটি পরীক্ষা করেছি এবং 'স্প্লিট / জয়েন' (162 মিলিসেকেন্ড) একই স্ট্রিংয়ের 10,000 পুনরাবৃত্তির জন্য 'স্প্লিট / কনক্যাট' (180 মিলিসেকেন্ড) এর চেয়ে ভাল পারফর্ম করলাম।
kernowcode

45

হেনসের উত্তরের উপর ভিত্তি করে আমি তার উত্তর দিয়ে কিছু পরীক্ষার পদ্ধতি তৈরি করেছি এবং কিছু যুক্ত, আরও অনুকূলিত, পদ্ধতিগুলি methods আমি ইনপুট স্ট্রিংয়ের আকারের ভিত্তিতে ফলাফলগুলি পৃথক করে দেখতে পেয়েছি। অতএব, আমি দুটি ফলাফলের সেট দিয়ে পরীক্ষা করেছি। দ্রুততম পদ্ধতিতে, লিঙ্কযুক্ত উত্সটির আরও দ্রুততর উপায় রয়েছে। তবে, যেহেতু এটি অনিরাপদ হিসাবে চিহ্নিত হয়েছে তাই আমি এটি ছেড়ে দিয়েছি।

দীর্ঘ ইনপুট স্ট্রিং ফলাফল:

  1. ইনপ্লেসচারআরে: 2021 এমএস ( সানসেটকোস্টের উত্তর ) - ( মূল উত্স )
  2. স্ট্রিং বিভক্ত হয়ে যোগ দিন: 4277 মিমি ( কর্নোকোডের উত্তর )
  3. স্ট্রিং রিডার: 6082 এমএস
  4. লিনিকিউ দেশীয় চর ব্যবহার করছে sশব্দীর স্থান: 7357 এমএস
  5. লিনকিউ: 7746 এমএস ( হেনকের উত্তর )
  6. ফর্মলুপ: 32320 এমএস
  7. RegexCompiled: 37157 ms
  8. রেজেজ: 42940 এমএস

সংক্ষিপ্ত ইনপুট স্ট্রিং ফলাফল:

  1. ইনপ্লেসচারআরে: 108 এমএস ( সানসেটকোস্টের উত্তর ) - ( আসল উত্স )
  2. স্ট্রিং বিভক্ত হয়ে যোগ দিন: 294 এমএস ( কর্নোকোডের উত্তর )
  3. স্ট্রিং রিডার: 327 এমএস
  4. ফর্মলুপ: 343 এমএস
  5. লিনিকিউ দেশীয় চর ব্যবহার করছে sশব্দীর স্থান: 624 এমএস ms
  6. লিনকিউ: 645 মিমি (হেনকের উত্তর )
  7. RegexCompiled: 1671 ms
  8. রেজেজ: 2599 এমএস

কোড :

public class RemoveWhitespace
{
    public static string RemoveStringReader(string input)
    {
        var s = new StringBuilder(input.Length); // (input.Length);
        using (var reader = new StringReader(input))
        {
            int i = 0;
            char c;
            for (; i < input.Length; i++)
            {
                c = (char)reader.Read();
                if (!char.IsWhiteSpace(c))
                {
                    s.Append(c);
                }
            }
        }

        return s.ToString();
    }

    public static string RemoveLinqNativeCharIsWhitespace(string input)
    {
        return new string(input.ToCharArray()
            .Where(c => !char.IsWhiteSpace(c))
            .ToArray());
    }

    public static string RemoveLinq(string input)
    {
        return new string(input.ToCharArray()
            .Where(c => !Char.IsWhiteSpace(c))
            .ToArray());
    }

    public static string RemoveRegex(string input)
    {
        return Regex.Replace(input, @"\s+", "");
    }

    private static Regex compiled = new Regex(@"\s+", RegexOptions.Compiled);
    public static string RemoveRegexCompiled(string input)
    {
        return compiled.Replace(input, "");
    }

    public static string RemoveForLoop(string input)
    {
        for (int i = input.Length - 1; i >= 0; i--)
        {
            if (char.IsWhiteSpace(input[i]))
            {
                input = input.Remove(i, 1);
            }
        }
        return input;
    }

    public static string StringSplitThenJoin(this string str)
    {
        return string.Join("", str.Split(default(string[]), StringSplitOptions.RemoveEmptyEntries));
    }

    public static string RemoveInPlaceCharArray(string input)
    {
        var len = input.Length;
        var src = input.ToCharArray();
        int dstIdx = 0;
        for (int i = 0; i < len; i++)
        {
            var ch = src[i];
            switch (ch)
            {
                case '\u0020':
                case '\u00A0':
                case '\u1680':
                case '\u2000':
                case '\u2001':
                case '\u2002':
                case '\u2003':
                case '\u2004':
                case '\u2005':
                case '\u2006':
                case '\u2007':
                case '\u2008':
                case '\u2009':
                case '\u200A':
                case '\u202F':
                case '\u205F':
                case '\u3000':
                case '\u2028':
                case '\u2029':
                case '\u0009':
                case '\u000A':
                case '\u000B':
                case '\u000C':
                case '\u000D':
                case '\u0085':
                    continue;
                default:
                    src[dstIdx++] = ch;
                    break;
            }
        }
        return new string(src, 0, dstIdx);
    }
}

পরীক্ষা :

[TestFixture]
public class Test
{
    // Short input
    //private const string input = "123 123 \t 1adc \n 222";
    //private const string expected = "1231231adc222";

    // Long input
    private const string input = "123 123 \t 1adc \n 222123 123 \t 1adc \n 222123 123 \t 1adc \n 222123 123 \t 1adc \n 222123 123 \t 1adc \n 222123 123 \t 1adc \n 222123 123 \t 1adc \n 222123 123 \t 1adc \n 222123 123 \t 1adc \n 222123 123 \t 1adc \n 222123 123 \t 1adc \n 222123 123 \t 1adc \n 222123 123 \t 1adc \n 222123 123 \t 1adc \n 222123 123 \t 1adc \n 222123 123 \t 1adc \n 222123 123 \t 1adc \n 222123 123 \t 1adc \n 222123 123 \t 1adc \n 222123 123 \t 1adc \n 222123 123 \t 1adc \n 222123 123 \t 1adc \n 222";
    private const string expected = "1231231adc2221231231adc2221231231adc2221231231adc2221231231adc2221231231adc2221231231adc2221231231adc2221231231adc2221231231adc2221231231adc2221231231adc2221231231adc2221231231adc2221231231adc2221231231adc2221231231adc2221231231adc2221231231adc2221231231adc2221231231adc2221231231adc222";

    private const int iterations = 1000000;

    [Test]
    public void RemoveInPlaceCharArray()
    {
        string s = null;
        var stopwatch = Stopwatch.StartNew();
        for (int i = 0; i < iterations; i++)
        {
            s = RemoveWhitespace.RemoveInPlaceCharArray(input);
        }

        stopwatch.Stop();
        Console.WriteLine("InPlaceCharArray: " + stopwatch.ElapsedMilliseconds + " ms");
        Assert.AreEqual(expected, s);
    }

    [Test]
    public void RemoveStringReader()
    {
        string s = null;
        var stopwatch = Stopwatch.StartNew();
        for (int i = 0; i < iterations; i++)
        {
            s = RemoveWhitespace.RemoveStringReader(input);
        }

        stopwatch.Stop();
        Console.WriteLine("String reader: " + stopwatch.ElapsedMilliseconds + " ms");
        Assert.AreEqual(expected, s);
    }

    [Test]
    public void RemoveLinqNativeCharIsWhitespace()
    {
        string s = null;
        var stopwatch = Stopwatch.StartNew();
        for (int i = 0; i < iterations; i++)
        {
            s = RemoveWhitespace.RemoveLinqNativeCharIsWhitespace(input);
        }

        stopwatch.Stop();
        Console.WriteLine("LINQ using native char.IsWhitespace: " + stopwatch.ElapsedMilliseconds + " ms");
        Assert.AreEqual(expected, s);
    }

    [Test]
    public void RemoveLinq()
    {
        string s = null;
        var stopwatch = Stopwatch.StartNew();
        for (int i = 0; i < iterations; i++)
        {
            s = RemoveWhitespace.RemoveLinq(input);
        }

        stopwatch.Stop();
        Console.WriteLine("LINQ: " + stopwatch.ElapsedMilliseconds + " ms");
        Assert.AreEqual(expected, s);
    }

    [Test]
    public void RemoveRegex()
    {
        string s = null;
        var stopwatch = Stopwatch.StartNew();
        for (int i = 0; i < iterations; i++)
        {
            s = RemoveWhitespace.RemoveRegex(input);
        }

        stopwatch.Stop();
        Console.WriteLine("Regex: " + stopwatch.ElapsedMilliseconds + " ms");

        Assert.AreEqual(expected, s);
    }

    [Test]
    public void RemoveRegexCompiled()
    {
        string s = null;
        var stopwatch = Stopwatch.StartNew();
        for (int i = 0; i < iterations; i++)
        {
            s = RemoveWhitespace.RemoveRegexCompiled(input);
        }

        stopwatch.Stop();
        Console.WriteLine("RegexCompiled: " + stopwatch.ElapsedMilliseconds + " ms");

        Assert.AreEqual(expected, s);
    }

    [Test]
    public void RemoveForLoop()
    {
        string s = null;
        var stopwatch = Stopwatch.StartNew();
        for (int i = 0; i < iterations; i++)
        {
            s = RemoveWhitespace.RemoveForLoop(input);
        }

        stopwatch.Stop();
        Console.WriteLine("ForLoop: " + stopwatch.ElapsedMilliseconds + " ms");

        Assert.AreEqual(expected, s);
    }

    [TestMethod]
    public void StringSplitThenJoin()
    {
        string s = null;
        var stopwatch = Stopwatch.StartNew();
        for (int i = 0; i < iterations; i++)
        {
            s = RemoveWhitespace.StringSplitThenJoin(input);
        }

        stopwatch.Stop();
        Console.WriteLine("StringSplitThenJoin: " + stopwatch.ElapsedMilliseconds + " ms");

        Assert.AreEqual(expected, s);
    }
}

সম্পাদনা করুন : কর্নোকোড থেকে একটি দুর্দান্ত একটি লাইনার পরীক্ষা করেছেন।


24

একটি বিকল্প কারণ এটি দেখতে বেশ সুন্দর দেখায় :) - দ্রষ্টব্য: মুরগির উত্তর এর মধ্যে দ্রুত est

input.ToCharArray()
 .Where(c => !Char.IsWhiteSpace(c))
 .Select(c => c.ToString())
 .Aggregate((a, b) => a + b);

1,000,000 লুপ পরীক্ষা করা হচ্ছে "This is a simple Test"

এই পদ্ধতিটি = 1.74 সেকেন্ড রেজেক্স
= 2.58 সেকেন্ড
new String(হেনস) = 0.82


1
কেন এই নিম্নমানের ছিল? এটি পুরোপুরি গ্রহণযোগ্য, প্রয়োজনীয়তা পূরণ করে, RegEx বিকল্পের চেয়ে দ্রুত কাজ করে এবং খুব পঠনযোগ্য?
ব্লুচিপ্পি

4
কারণ এটি অনেক ছোট লেখা যেতে পারে: নতুন স্ট্রিং (ইনপুট.উইয়ার (সি =>! চর.আইসওয়াইটসাইট) (গ))। টুআর্রে ());
বাস স্মিথ

7
সত্য হতে পারে - তবে উত্তরটি এখনও দাঁড়িয়ে আছে, পাঠযোগ্য, রেগেক্সের চেয়ে দ্রুত এবং পছন্দসই ফলাফল উত্পন্ন করে। অন্যান্য উত্তরগুলির অনেকগুলি এটির পরে রয়েছে ... সুতরাং একটি ডাউনভোটটি বোঝায় না।
ব্লুচিপ্পি 12 '12

2
"0.82" এর জন্য কি কোনও ইউনিট রয়েছে? বা এটি একটি আপেক্ষিক পরিমাপ (82%)? আপনার উত্তরটি আরও স্পষ্ট করতে আপনি সম্পাদনা করতে পারেন?
পিটার মর্টেনসেন

20

আমি দেখেছি একটা চমৎকার লেখার আপ এই CodeProject উপর ফেলিপে মাচাদো দ্বারা (সাহায্যে দ্বারা রিচার্ড রবার্টসন )

তিনি দশটি বিভিন্ন পদ্ধতি পরীক্ষা করেছিলেন। এটি দ্রুততম অনিরাপদ সংস্করণ ...

public static unsafe string TrimAllWithStringInplace(string str) {
    fixed (char* pfixed = str) {
        char* dst = pfixed;
        for (char* p = pfixed; *p != 0; p++)

            switch (*p) {

                case '\u0020': case '\u00A0': case '\u1680': case '\u2000': case '\u2001':

                case '\u2002': case '\u2003': case '\u2004': case '\u2005': case '\u2006':

                case '\u2007': case '\u2008': case '\u2009': case '\u200A': case '\u202F':

                case '\u205F': case '\u3000': case '\u2028': case '\u2029': case '\u0009':

                case '\u000A': case '\u000B': case '\u000C': case '\u000D': case '\u0085':
                    continue;

                default:
                    *dst++ = *p;
                    break;
            }

        return new string(pfixed, 0, (int)(dst - pfixed));
    }
}

এবং দ্রুততম নিরাপদ সংস্করণ ...

public static string TrimAllWithInplaceCharArray(string str) {

    var len = str.Length;
    var src = str.ToCharArray();
    int dstIdx = 0;

    for (int i = 0; i < len; i++) {
        var ch = src[i];

        switch (ch) {

            case '\u0020': case '\u00A0': case '\u1680': case '\u2000': case '\u2001':

            case '\u2002': case '\u2003': case '\u2004': case '\u2005': case '\u2006':

            case '\u2007': case '\u2008': case '\u2009': case '\u200A': case '\u202F':

            case '\u205F': case '\u3000': case '\u2028': case '\u2029': case '\u0009':

            case '\u000A': case '\u000B': case '\u000C': case '\u000D': case '\u0085':
                continue;

            default:
                src[dstIdx++] = ch;
                break;
        }
    }
    return new string(src, 0, dstIdx);
}

স্টায়ান স্ট্যান্ডাহেলের স্ট্যাক ওভারফ্লোতে কিছু দুর্দান্ত স্বতন্ত্র বেঞ্চমার্ক রয়েছে যা এও দেখায় যে ফিলিপের ফাংশনটি পরবর্তী দ্রুততম ফাংশনের চেয়ে প্রায় 300% দ্রুততর কীভাবে হয়।


আমি এটি সি ++ তে অনুবাদ করার চেষ্টা করেছি তবে কিছুটা আটকে আছি। কোনও ধারণা কেন আমার বন্দর ব্যর্থ হতে পারে? stackoverflow.com/questions/42135922/…
জন কেজ

2
আমি প্রতিহত করতে পারি না। আপনি উল্লেখ নিবন্ধটির মন্তব্য বিভাগে দেখুন। আপনি আমাকে "বাস্কেটবলের সফটওয়্যার" হিসাবে খুঁজে পাবেন। তিনি এবং এটি নিয়ে কিছুক্ষণ একসাথে কাজ করেছিলেন। এই সমস্যাটি আবার ফিরে আসলে আমি এই সম্পর্কে সম্পূর্ণরূপে ভুলে গিয়েছিলাম। ভাল স্মৃতি জন্য ধন্যবাদ। :)
রিচার্ড রবার্টসন

1
এবং যদি আপনি কেবল অতিরিক্ত ডাব্লুএস অপসারণ করতে চান? এই স্ট্যাকওভারফ্লো.com/ প্রশ্নগুলি / 17770202/… মোড সম্পর্কে কী ?
টম

দ্রুততমটি কিছুটা ধীরে ধীরে ;-) এখানে কন্টেইনার পারফিউম হিসাবে স্ট্রিং ভাল হয় (অ্যাপ্লিকেশন 4:15 থেকে 3:55 => 8.5% কম, তবে বাম স্ট্রিং 3:30 => 21.4% কম থাকে এবং প্রোফাইলার প্রায় 50% ব্যয় করে দেখায় এই পদ্ধতি)। সুতরাং বাস্তব লাইভ স্ট্রিংয়ে এখানে ব্যবহৃত (ধীর) অ্যারে রূপান্তরটির তুলনায় প্রায় 40% দ্রুত হওয়া উচিত।
টম

15

যদি আপনার দুর্দান্ত পারফরম্যান্সের প্রয়োজন হয় তবে আপনার এই ক্ষেত্রে লিনকিউ এবং নিয়মিত প্রকাশগুলি এড়ানো উচিত। আমি কিছু পারফরম্যান্স বেঞ্চমার্কিং করেছি এবং মনে হচ্ছে আপনি যদি স্ট্রিংয়ের শুরু এবং শেষ থেকে সাদা স্থানটি ছিনিয়ে নিতে চান তবে স্ট্রিং.ট্রিম () আপনার চূড়ান্ত ফাংশন।

আপনার যদি কোনও স্ট্রিং থেকে সমস্ত সাদা স্পেসটি ফেলা প্রয়োজন, নিম্নলিখিত পদ্ধতিটি এখানে পোস্ট করা সমস্তর চেয়ে দ্রুত কাজ করে:

    public static string RemoveWhitespace(this string input)
    {
        int j = 0, inputlen = input.Length;
        char[] newarr = new char[inputlen];

        for (int i = 0; i < inputlen; ++i)
        {
            char tmp = input[i];

            if (!char.IsWhiteSpace(tmp))
            {
                newarr[j] = tmp;
                ++j;
            }
        }
        return new String(newarr, 0, j);
    }

আমি আপনার বেঞ্চমার্কিংয়ের বিশদ জানতে আগ্রহী হব - আমি সন্দেহবাদী নই তবে লিনকের সাথে জড়িত ওভারহেড সম্পর্কে আমি কৌতূহলী ছিলাম। এটা কত খারাপ ছিল?
মার্ক মেউর

আমি সমস্ত পরীক্ষা পুনরায় চালিত করি নি, তবে আমি এটি অনেক কিছুই মনে করতে পারি: লিঙ্ককে জড়িত সমস্ত কিছুই এটি ছাড়াই যে কোনও কিছুর চেয়ে ধীর ছিল। স্ট্রিং / চর ফাংশন এবং কনস্ট্রাক্টরের সমস্ত চতুর ব্যবহারের ফলে লিনক ব্যবহার করা গেলে কোনও পার্থক্য নেই।
জেএইচএম

11

রেজেক্স ওভারকিল; কেবল স্ট্রিংয়ে এক্সটেনশন ব্যবহার করুন (ধন্যবাদ হেন্ক)। এটি তুচ্ছ এবং কাঠামোর অংশ হওয়া উচিত ছিল। যাইহোক, এখানে আমার বাস্তবায়ন:

public static partial class Extension
{
    public static string RemoveWhiteSpace(this string self)
    {
        return new string(self.Where(c => !Char.IsWhiteSpace(c)).ToArray());
    }
}

এটি মূলত একটি অপ্রয়োজনীয় উত্তর (রেজেক্স ওভারকিল, তবে প্রদত্ত একটির চেয়ে দ্রুত সমাধান - এবং এটি ইতিমধ্যে গৃহীত?)
W1ll1amvl

আপনি কীভাবে একটি স্ট্রিংয়ে লিনক এক্সটেনশন পদ্ধতি ব্যবহার করতে পারেন? কোনটি ব্যবহার করে আমি অন্যকে মিস করছি তা System.Linq
অনুধাবন

ঠিক আছে দেখে মনে হচ্ছে এটি পিসিএলে উপলভ্য নয়, মাইক্রোসফ্ট স্ট্রিং বাস্তবায়নে আইনিম্যুয়াল <চার> শর্তযুক্ত ... এবং আমি প্রোফাইল
259

4

RegEx সমাধানের জন্য এখানে একটি সরল রৈখিক বিকল্প। কোনটি দ্রুত তা আমি নিশ্চিত নই; আপনি এটি মানদণ্ড করতে হবে।

static string RemoveWhitespace(string input)
{
    StringBuilder output = new StringBuilder(input.Length);

    for (int index = 0; index < input.Length; index++)
    {
        if (!Char.IsWhiteSpace(input, index))
        {
            output.Append(input[index]);
        }
    }
    return output.ToString();
}

3

আমার শূণ্যস্থানগুলির সাথে একটি স্ট্রিংয়ে শ্বেত স্থানটি প্রতিস্থাপন করতে হবে, তবে ফাঁকা স্থানগুলি নয় not উদাহরণস্বরূপ, আমাকে নিম্নলিখিতগুলির মতো কিছু রূপান্তর করতে হবে:

"a b   c\r\n d\t\t\t e"

প্রতি

"a b c d e"

আমি নিম্নলিখিত পদ্ধতিটি ব্যবহার করেছি

private static string RemoveWhiteSpace(string value)
{
    if (value == null) { return null; }
    var sb = new StringBuilder();

    var lastCharWs = false;
    foreach (var c in value)
    {
        if (char.IsWhiteSpace(c))
        {
            if (lastCharWs) { continue; }
            sb.Append(' ');
            lastCharWs = true;
        }
        else
        {
            sb.Append(c);
            lastCharWs = false;
        }
    }
    return sb.ToString();
}

2

আমি ধরে নিলাম আপনার এক্সএমএল প্রতিক্রিয়াটি এরকম দেখাচ্ছে:

var xml = @"<names>
                <name>
                    foo
                </name>
                <name>
                    bar
                </name>
            </names>";

এক্সএমএল প্রক্রিয়া করার সর্বোত্তম উপায় হ'ল এক্সএমএল পার্সার ব্যবহার করা, যেমন লিনকু থেকে এক্সএমএল :

var doc = XDocument.Parse(xml);

var containsFoo = doc.Root
                     .Elements("name")
                     .Any(e => ((string)e).Trim() == "foo");

একবার আমি যাচাই করে দেখি যে কোনও নির্দিষ্ট <নাম> ট্যাগের যথাযথ মান রয়েছে, আমি শেষ করেছি। দস্তাবেজটি বিশ্লেষণ করার কি কিছু ওভারহেড থাকবে না?
কোরি ওগবার্ন

4
অবশ্যই, এটি কিছু ওভারহেড আছে তবে এটি সঠিক হওয়ার সুবিধা রয়েছে। যেমন রেগেক্সের উপর ভিত্তি করে একটি সমাধান সঠিকভাবে পাওয়া অনেক বেশি কঠিন। যদি আপনি নির্ধারণ করেন যে একটি লিনকিউ থেকে এক্সএমএল সমাধান খুব ধীর, আপনি সর্বদা দ্রুত কিছু দিয়ে প্রতিস্থাপন করতে পারেন। তবে আপনার জানা উচিত যে সঠিকটি খুব ধীর।
dtb

এটি আমার নিয়োগকর্তার ব্যাকএন্ড সার্ভারগুলিতে চলছে। আমি যা খুঁজছি লাইটওয়েট। আমি এমন কিছু চাই না যা "কেবলমাত্র কাজ করে" তবে অনুকূল is
কোরি ওগবার্ন

4
এক্স নেট থেকে এক্সএমএলকে সঠিকভাবে কাজ করার জন্য লিনক টু এক্সএমএল অন্যতম হালকা উপায়
ডিটিবি

1

এখানে আরও একটি রূপ রয়েছে:

public static string RemoveAllWhitespace(string aString)
{
  return String.Join(String.Empty, aString.Where(aChar => aChar !Char.IsWhiteSpace(aChar)));
}

অন্যান্য বেশিরভাগ সমাধানের মতোই, আমি সম্পূর্ণ বেঞ্চমার্ক পরীক্ষা করিনি, তবে এটি আমার উদ্দেশ্যগুলির জন্য যথেষ্ট ভাল কাজ করে।


1

আমরা ব্যবহার করতে পারি:

    public static string RemoveWhitespace(this string input)
    {
        if (input == null)
            return null;
        return new string(input.ToCharArray()
            .Where(c => !Char.IsWhiteSpace(c))
            .ToArray());
    }

এটি উপরের হেনকের উত্তরের মতো প্রায় একই রকম। পার্থক্য কেবলমাত্র আপনি যাচাই করেন null
কোরি ওগবার্ন

হ্যাঁ,
নালটির

1
সম্ভবত এটি তার উত্তর সম্পর্কে একটি মন্তব্য করা উচিত ছিল। আপনি খুশি যদিও আপনি এটি উত্থাপিত। আমি জানতাম না নথ বস্তুগুলিতে এক্সটেনশন পদ্ধতিগুলি কল করা যেতে পারে।
কোরি ওগবার্ন

0

আমি সত্য হতে বিভিন্ন ফলাফল খুঁজে পেয়েছি। আমি সমস্ত শ্বেত স্পেসকে একটি একক স্থানের সাথে প্রতিস্থাপন করার চেষ্টা করছি এবং রেজেক্স অত্যন্ত ধীর ছিল।

return( Regex::Replace( text, L"\s+", L" " ) );

আমার জন্য সর্বাধিক অনুকূল কী কাজ করেছে (সি ++ ক্লিমে) তা ছিল:

String^ ReduceWhitespace( String^ text )
{
  String^ newText;
  bool    inWhitespace = false;
  Int32   posStart = 0;
  Int32   pos      = 0;
  for( pos = 0; pos < text->Length; ++pos )
  {
    wchar_t cc = text[pos];
    if( Char::IsWhiteSpace( cc ) )
    {
      if( !inWhitespace )
      {
        if( pos > posStart ) newText += text->Substring( posStart, pos - posStart );
        inWhitespace = true;
        newText += L' ';
      }
      posStart = pos + 1;
    }
    else
    {
      if( inWhitespace )
      {
        inWhitespace = false;
        posStart = pos;
      }
    }
  }

  if( pos > posStart ) newText += text->Substring( posStart, pos - posStart );

  return( newText );
}

আমি প্রতিটি চরিত্রকে আলাদা করে প্রতিস্থাপন করে উপরের রুটিনটি প্রথমে চেষ্টা করেছি, তবে ফাঁকা স্থানবিহীন বিভাগগুলির জন্য সাবস্ট্রিংগুলি করতে গিয়েছিলাম। 1,200,000 অক্ষরের স্ট্রিংয়ে প্রয়োগ করার সময়:

  • উপরের রুটিনটি এটি 25 সেকেন্ডের মধ্যে হয়ে যায়
  • উপরের রুটিন + 95 সেকেন্ডের মধ্যে পৃথক অক্ষর প্রতিস্থাপন
  • রেজেক্স 15 মিনিটের পরে বাতিল হয়ে গেছে।
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.