web-dev-qa-db-fra.com

Remplacer plusieurs caractères dans une chaîne C #

Existe-t-il un meilleur moyen de remplacer les chaînes?

Je suis surpris que Replace ne prenne pas dans un tableau de caractères ou un tableau de chaînes. Je suppose que je pourrais écrire ma propre extension, mais j’étais curieux de savoir s’il existe un moyen plus efficace de procéder comme suit. Remarquez que le dernier remplacement est une chaîne et non un caractère.

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

Vous pouvez utiliser une expression régulière de remplacement.

s/[;,\t\r ]|[\n]{2}/\n/g
  • s/ au début signifie une recherche
  • Les caractères entre [ et ] sont les caractères à rechercher (dans n'importe quel ordre)
  • Le second / délimite le texte à rechercher et le texte à remplacer

En anglais, cela se lit comme suit:

"Recherchez ; ou , ou \t ou \r ou (espace) ou exactement deux \n séquentiels et remplacez-le par \n"

En C #, vous pouvez effectuer les opérations suivantes: (après avoir importé System.Text.RegularExpressions)

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

Si vous vous sentez particulièrement malin et que vous ne voulez pas utiliser Regex:

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);

Vous pouvez également inclure cela dans une méthode d'extension avec peu d'effort.

Edit: Ou bien attendez 2 minutes et je finirai quand même par l'écrire :)

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 );
   }
}

Et voila ...

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

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

Vous pouvez utiliser la fonction Aggréger de Linq:

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'));

Voici la méthode d'extension:

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

C'est le moyen le plus court:

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

Ohhh, l'horreur de la performance! La réponse est un peu dépassée, mais quand même ...

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
John Whiter

Les chaînes ne sont que des tableaux de caractères immuables

Vous avez juste besoin de le rendre mutable:

  • soit en utilisant StringBuilder
  • allez dans le monde unsafe et jouez avec les pointeurs (dangereux cependant)

et essayez de parcourir le tableau de caractères le moins de fois possible.

Exemple avec StringBuilder

    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;
            }
        }
    }

Ensuite, il vous suffit de l'utiliser comme ça:

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

Vous pouvez aussi simplement écrire ces méthodes d'extension string , et les mettre quelque part dans votre solution:

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;
    }
}


Appelez-les comme ça:

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

xyBxyDxy


Et ça:

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

xyCxyF

2

Utilisez RegEx.Replace, quelque chose comme ceci:

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

Voici plus d'informations sur ceci Documentation MSDN pour RegEx.Replace

1
Dmitry Samuylov

Performance-Wise, cela n’est peut-être pas la meilleure solution, mais cela fonctionne.

var str = "filename:with&bad$separators.txt";
char[] charArray = new char[] { '#', '%', '&', '{', '}', '\\', '<', '>', '*', '?', '/', ' ', '$', '!', '\'', '"', ':', '@' };
foreach (var singleChar in charArray)
{
   str = str.Replace(singleChar, '_');
}
1
Daniel Székely
string ToBeReplaceCharacters = @"~()@#$%&amp;+,'&quot;&lt;&gt;|;\/*?";
string fileName = "filename;with<bad:separators?";

foreach (var RepChar in ToBeReplaceCharacters)
{
    fileName = fileName.Replace(RepChar.ToString(), "");
}
0
Jignesh Bhayani