MartinS
MartinS

Reputation: 145

c# replace each instance of a character selection in a string

I've found many references to do similar to this but none seem to be exactly what I'm after, so hoping someone could help.
In simple terms, I want to take a string entered by a user (into a Winform input), and firstly strip out any blanks, then replace any of a list of 'illegal' characters with the UK currency symbol (£). The requirement is for the input to be used but the file that is generated by the process has the modified filename.
I wrote a function (based on an extension method) but it's not working quite as expected:

public static class ExtensionMethods
    {
        public static string Replace(this string s, char[] separators, string newVal)
        {
            var temp = s.Split(separators, StringSplitOptions.RemoveEmptyEntries);
            return String.Join(newVal, temp);
        }
    }

public static string RemoveUnwantedChars(string enteredName, char[] unwanted, string rChar)
    {
        return enteredName.Replace(unwanted, rChar);
    }

Which in my code, I've called twice:

char[] blank = { ' ' };
string ename = Utilities.RemoveUnwantedChars(this.txtTableName.Text, blank, string.Empty);

char[] unwanted = { '(', ')', '.', '%', '/', '&', '+' };
string fname = Utilities.RemoveUnwantedChars(ename, unwanted, "£");

If I enter a string that contains at least one space, all of the characters above and some other letters (for example, " (GH) F16.5% M X/Y&1+1"), I get the following results:
ename = "(GH)F16.5%MX/Y&1+1" - this is correct in that it has removed the blanks.
fname = "GH£F16£5£MX£Y£1£1" - this hasn't worked correctly in that it has not replaced the first character but removed it.
The rest of the characters have been correctly replaced. It only occurs when one of the 'illegal' characters is at the start of the string - if my string was "G(H) F16.5% M X/Y&1+1", I would correctly get "G£H£F16£5£MX£Y£1£1". It also replaces multiple 'illegal' characters with one '£', so "M()GX+.1" would become "M£GX£1" but should be "M££GX££1".

Upvotes: 1

Views: 125

Answers (3)

Matthew Watson
Matthew Watson

Reputation: 109597

The problem is occuring because string.Join() only puts separators between substrings - it will never put one at the start.

One possible solution is to avoid using string.Join() and write Replace() like this instead:

public static class ExtensionMethods
{
    public static string Replace(this string s, char[] separators, string newVal)
    {
        var sb = new StringBuilder(s);

        foreach (char ch in separators)
        {
            string target = new string(ch, 1);
            sb.Replace(target, newVal);
        }

        return sb.ToString();
    }
}

Upvotes: 2

Nemanja Todorovic
Nemanja Todorovic

Reputation: 2800

When you use split method in your Replace function you get following strings: GH, F16, 5, MX, Y, 1, 1. When you join them with your newVal you get: GH + newVal + F16 + newVal + ... thus omitting first replaced character.

You would probably need some special case to check if first char is "illegal" and put newVal at start of your string.

Upvotes: 0

Pikoh
Pikoh

Reputation: 7703

I think the problem is in your Replace extension. You are splitting in this line

var temp = s.Split(separators, StringSplitOptions.RemoveEmptyEntries);

You are removing empty entries causing the unexpected result. Use this instead:

var temp = s.Split(separators, StringSplitOptions.None);

Upvotes: 3

Related Questions