সি # স্ট্রিংয়ে একাধিক অক্ষর প্রতিস্থাপন করুন


178

স্ট্রিংগুলি প্রতিস্থাপনের জন্য আরও ভাল উপায় কি?

আমি অবাক হয়েছি যে প্রতিস্থাপনটি একটি অক্ষর অ্যারে বা স্ট্রিং অ্যারে গ্রহণ করে না। আমি অনুমান করি যে আমি নিজের এক্সটেনশনটি লিখতে পারি তবে আমি কৌতূহলী ছিলাম যদি নিম্নলিখিতগুলি করার মতো আরও ভাল কোনও বিল্ট থাকে? লক্ষ করুন শেষ প্রতিস্থাপনটি একটি অক্ষর নয় স্ট্রিং।

myString.Replace(';', '\n').Replace(',', '\n').Replace('\r', '\n').Replace('\t', '\n').Replace(' ', '\n').Replace("\n\n", "\n");

উত্তর:


206

আপনি একটি প্রতিস্থাপন নিয়মিত এক্সপ্রেশন ব্যবহার করতে পারেন।

s/[;,\t\r ]|[\n]{2}/\n/g
  • s/ শুরুতে একটি অনুসন্ধান মানে
  • এর মধ্যে [এবং ]এর মধ্যে থাকা অক্ষরগুলি (কোনও ক্রমে) অনুসন্ধান করতে হবে
  • দ্বিতীয়টি /অনুসন্ধানের জন্য পাঠ্য এবং প্রতিস্থাপন পাঠ্যের সীমাবদ্ধ করে

ইংরাজীতে, এটি পড়ে:

"এর জন্য অনুসন্ধান ;বা ,বা \tবা \rবা (স্থান) অথবা ঠিক দুই অনুক্রমিক \nএবং সঙ্গে এটি প্রতিস্থাপন \n"

সি # তে, আপনি নিম্নলিখিতগুলি করতে পারেন: (আমদানির পরে System.Text.RegularExpressions)

Regex pattern = new Regex("[;,\t\r ]|[\n]{2}");
pattern.Replace(myString, "\n");

2
\tএবং \rঅন্তর্ভুক্ত করা হয় \s। সুতরাং আপনার regex সমতুল্য [;,\s]
নালুউজারএক্সেপশন

3
এবং \sআসলে এর সমতুল্য [ \f\n\r\t\v]তাই আপনি সেখানে কিছু জিনিস অন্তর্ভুক্ত করছেন যা মূল প্রশ্নের মধ্যে ছিল না। সংক্ষেপে, মূল প্রশ্নটি জিজ্ঞাসা করে Replace("\n\n", "\n")যার জন্য আপনার রেজেক্স পরিচালনা করে না।
নালুউজারএক্সেপশন

11
দয়া করে বিবেচনা করুন যে কোনও সরল প্রতিস্থাপন অপারেশনগুলির জন্য যা ব্যবহারকারী দ্বারা কনফিগার করা যায় না, নিয়মিত এক্সপ্রেশন ব্যবহার করা অনুকূল নয় কারণ এটি নিয়মিত স্ট্রিং অপারেশনের তুলনায় খুব ধীর গতির, "সি # রেজেক্স পারফরম্যান্স রিপ্লেসমেন্ট" অনুসন্ধান করার সময় আমি খুঁজে পেয়েছিলাম এমন প্রথম একটি বেঞ্চমার্ক নিবন্ধ অনুসারে বার ধীর।
খুব

আহ রেগেক্স, পাওয়ারের হায়ারোগ্লাইফস! আমি এখানে কেবল দেখতে পাচ্ছি নিয়মিত প্রকাশের মানব পাঠযোগ্যতা; অনেক তাদের বুঝতে অস্বীকার করে। যারা কম জটিল বিকল্প খুঁজছেন তাদের জন্য আমি সম্প্রতি নীচে একটি সমাধান যুক্ত করেছি।
সুনুন ןɐ কিউপি

সুতরাং আমরা কীভাবে লিখব যদি আমরা একাধিক অক্ষরের সাথে একাধিক অক্ষর প্রতিস্থাপন করতে চাই?
হবিপ ওউজ

114

আপনি যদি বিশেষত চালাক বোধ করছেন এবং রেজেজ ব্যবহার করতে চান না:

char[] separators = new char[]{' ',';',',','\r','\t','\n'};

string s = "this;is,\ra\t\n\n\ntest";
string[] temp = s.Split(separators, StringSplitOptions.RemoveEmptyEntries);
s = String.Join("\n", temp);

আপনি এটিকে সামান্য চেষ্টা করেও একটি এক্সটেনশন পদ্ধতিতে মোড়ানো করতে পারেন।

সম্পাদনা করুন: অথবা মাত্র 2 মিনিট অপেক্ষা করুন এবং আমি যাইহোক এটি লেখা শেষ করব :)

public static class ExtensionMethods
{
   public static string Replace(this string s, char[] separators, string newVal)
   {
       string[] temp;

       temp = s.Split(separators, StringSplitOptions.RemoveEmptyEntries);
       return String.Join( newVal, temp );
   }
}

এবং ভয়েলা ...

char[] separators = new char[]{' ',';',',','\r','\t','\n'};
string s = "this;is,\ra\t\n\n\ntest";

s = s.Replace(separators, "\n");

খুব স্মৃতি-অক্ষম, বিশেষত বৃহত্তর স্ট্রিংয়ের জন্য।
মার্সিনজুরাসেকেরেক

@ মারকিন জুরাসেকল লোল ... সম্ভবত আমি প্রথমবারের মতো কারও দাবি শুনেছি যে অন্তর্নির্মিত স্ট্রিং পদ্ধতিগুলি নিয়মিত অভিব্যক্তির চেয়ে কম স্মৃতিশক্তি দক্ষ।
পল ওয়ালস

10
তুমি ঠিক বলছো. আমি এটি পোস্ট করার আগে আমার পরিমাপ করা উচিত ছিল। আমি বেঞ্চমার্ক চালনা করি এবং Regex.Replaceএকাধিক string.Replaceকলের চেয়ে একটানা 8x এর চেয়ে বেশি ধীর । এবং 4x ধীর চেয়ে Split+ + Join। দেখুন gist.github.com/MarcinJuraszek/c1437d925548561ba210a1c6ed144452
MarcinJuraszek

1
চমৎকার সমাধান! একটি ছোট অ্যাডন। দুর্ভাগ্যক্রমে, আপনি যদি প্রথম অক্ষর (গুলি) পাশাপাশি প্রতিস্থাপন করতে চান তবে এটি কাজ করবে না। বলুন আপনি উদাহরণ স্ট্রিংয়ে 't' অক্ষরটি প্রতিস্থাপন করতে চান। বিভক্ত পদ্ধতিটি কেবল প্রথম শব্দের 'এটি' এর 'টি' বাদ দেবে কারণ এটি একটি খালি পদার্থ। আপনি যদি স্ট্রিংস্প্লিটঅપ્শনগুলি ব্যবহার করেন Remove সরানএম্পটিএন্ট্রিগুলির পরিবর্তে কোনও না, স্প্লিট এন্ট্রি ছেড়ে দেবে এবং যোগদানের পদ্ধতিটি পরিবর্তে পৃথককারী চরিত্রটি যুক্ত করবে। আশা করি এটি সহায়তা করে
পিয়েরে

58

আপনি লিনকের সমষ্টিগত ফাংশনটি ব্যবহার করতে পারেন:

string s = "the\nquick\tbrown\rdog,jumped;over the lazy fox.";
char[] chars = new char[] { ' ', ';', ',', '\r', '\t', '\n' };
string snew = chars.Aggregate(s, (c1, c2) => c1.Replace(c2, '\n'));

এখানে এক্সটেনশন পদ্ধতিটি রয়েছে:

public static string ReplaceAll(this string seed, char[] chars, char replacementCharacter)
{
    return chars.Aggregate(seed, (str, cItem) => str.Replace(cItem, replacementCharacter));
}

এক্সটেনশন পদ্ধতি ব্যবহারের উদাহরণ:

string snew = s.ReplaceAll(chars, '\n');

21

এটি সবচেয়ে সংক্ষিপ্ততম উপায়:

myString = Regex.Replace(myString, @"[;,\t\r ]|[\n]{2}", "\n");

1
আপনার যখন প্রারম্ভিকগুলির মধ্যে এটি প্রয়োজন তখন এই একটি লাইনারও সহায়তা করে।
Guney Ozsan

8

ওহ, পারফরম্যান্স হরর! উত্তরটি কিছুটা পুরানো তবে এখনও ...

public static class StringUtils
{
    #region Private members

    [ThreadStatic]
    private static StringBuilder m_ReplaceSB;

    private static StringBuilder GetReplaceSB(int capacity)
    {
        var result = m_ReplaceSB;

        if (null == result)
        {
            result = new StringBuilder(capacity);
            m_ReplaceSB = result;
        }
        else
        {
            result.Clear();
            result.EnsureCapacity(capacity);
        }

        return result;
    }


    public static string ReplaceAny(this string s, char replaceWith, params char[] chars)
    {
        if (null == chars)
            return s;

        if (null == s)
            return null;

        StringBuilder sb = null;

        for (int i = 0, count = s.Length; i < count; i++)
        {
            var temp = s[i];
            var replace = false;

            for (int j = 0, cc = chars.Length; j < cc; j++)
                if (temp == chars[j])
                {
                    if (null == sb)
                    {
                        sb = GetReplaceSB(count);
                        if (i > 0)
                            sb.Append(s, 0, i);
                    }

                    replace = true;
                    break;
                }

            if (replace)
                sb.Append(replaceWith);
            else
                if (null != sb)
                    sb.Append(temp);
        }

        return null == sb ? s : sb.ToString();
    }
}

7

স্ট্রিংগুলি কেবল স্থাবর চর অ্যারে

আপনার কেবল এটিকে পরিবর্তনযোগ্য করতে হবে:

  • হয় ব্যবহার করে StringBuilder
  • unsafeবিশ্বে যান এবং পয়েন্টারগুলির সাথে খেলুন (যদিও বিপজ্জনক)

এবং অক্ষরের অ্যারে দিয়ে পুনরাবৃত্তি করার চেষ্টা করুন সর্বনিম্ন পরিমাণ। HashSetএখানে নোট করুন, কারণ এটি লুপের ভিতরে অক্ষর ক্রমটি অতিক্রম করতে এড়িয়ে চলে। আপনার যদি আরও দ্রুত অনুসন্ধানের প্রয়োজন হয় তবে আপনি HashSetএকটি অপ্টিমাইজড লুকআপ দ্বারা প্রতিস্থাপন করতে পারেন char(একটি উপর ভিত্তি করে array[256])।

স্ট্রিংবিল্ডারের সাথে উদাহরণ

public static void MultiReplace(this StringBuilder builder, 
    char[] toReplace, 
    char replacement)
{
    HashSet<char> set = new HashSet<char>(toReplace);
    for (int i = 0; i < builder.Length; ++i)
    {
        var currentCharacter = builder[i];
        if (set.Contains(currentCharacter))
        {
            builder[i] = replacement;
        }
    }
}

সম্পাদনা করুন - অনুকূলিত সংস্করণ

public static void MultiReplace(this StringBuilder builder, 
    char[] toReplace,
    char replacement)
{
    var set = new bool[256];
    foreach (var charToReplace in toReplace)
    {
        set[charToReplace] = true;
    }
    for (int i = 0; i < builder.Length; ++i)
    {
        var currentCharacter = builder[i];
        if (set[currentCharacter])
        {
            builder[i] = replacement;
        }
    }
}

তারপরে আপনি কেবল এটির মতো ব্যবহার করুন:

var builder = new StringBuilder("my bad,url&slugs");
builder.MultiReplace(new []{' ', '&', ','}, '-');
var result = builder.ToString();

মনে রাখবেন যে স্ট্রিংগুলি wchar_tনেট এ রয়েছে, আপনি সমস্ত সম্ভাব্য অক্ষরের কেবলমাত্র একটি উপসেট প্রতিস্থাপন করছেন (এবং এটির অনুকূলকরণের জন্য আপনার 65536 বুল দরকার হবে ...)
গোগ

3

আপনি এই স্ট্রিং এক্সটেনশন পদ্ধতিগুলি সহজেই লিখতে পারেন এবং এগুলিকে আপনার সমাধানে কোথাও রেখে দিতে পারেন:

using System.Text;

public static class StringExtensions
{
    public static string ReplaceAll(this string original, string toBeReplaced, string newValue)
    {
        if (string.IsNullOrEmpty(original) || string.IsNullOrEmpty(toBeReplaced)) return original;
        if (newValue == null) newValue = string.Empty;
        StringBuilder sb = new StringBuilder();
        foreach (char ch in original)
        {
            if (toBeReplaced.IndexOf(ch) < 0) sb.Append(ch);
            else sb.Append(newValue);
        }
        return sb.ToString();
    }

    public static string ReplaceAll(this string original, string[] toBeReplaced, string newValue)
    {
        if (string.IsNullOrEmpty(original) || toBeReplaced == null || toBeReplaced.Length <= 0) return original;
        if (newValue == null) newValue = string.Empty;
        foreach (string str in toBeReplaced)
            if (!string.IsNullOrEmpty(str))
                original = original.Replace(str, newValue);
        return original;
    }
}


তাদের এইভাবে কল করুন:

"ABCDE".ReplaceAll("ACE", "xy");

xyBxyDxy


এবং এই:

"ABCDEF".ReplaceAll(new string[] { "AB", "DE", "EF" }, "xy");

xyCxyF


2

RegEx.Replace ব্যবহার করুন, এরকম কিছু:

  string input = "This is   text with   far  too   much   " + 
                 "whitespace.";
  string pattern = "[;,]";
  string replacement = "\n";
  Regex rgx = new Regex(pattern);
  string result = rgx.Replace(input, replacement);

RegEx.Replace এর জন্য এই এমএসডিএন ডকুমেন্টেশন সম্পর্কে আরও তথ্য এখানে


1

পারফরম্যান্স-ওয়াইজ এটি সম্ভবত সেরা সমাধান না হতে পারে তবে এটি কার্যকর হয়।

var str = "filename:with&bad$separators.txt";
char[] charArray = new char[] { '#', '%', '&', '{', '}', '\\', '<', '>', '*', '?', '/', ' ', '$', '!', '\'', '"', ':', '@' };
foreach (var singleChar in charArray)
{
   str = str.Replace(singleChar, '_');
}

1
string ToBeReplaceCharacters = @"~()@#$%&amp;+,'&quot;&lt;&gt;|;\/*?";
string fileName = "filename;with<bad:separators?";

foreach (var RepChar in ToBeReplaceCharacters)
{
    fileName = fileName.Replace(RepChar.ToString(), "");
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.