183 votes

Supprimer des caractères d'une chaîne C#

Comment puis-je supprimer des caractères d'une chaîne de caractères ? Par exemple : "My name @is ,Wan.;'; Wan" .

Je voudrais supprimer les caractères '@', ',', '.', ';', '\'' de cette chaîne pour qu'elle devienne "My name is Wan Wan"

0 votes

Le site vraiment correct La façon de le faire est expliquée ici même dans les documents de MSFT : docs.microsoft.com/fr/us/dotnet/standard/base-types/ Ça ne pourrait pas être plus facile.

214voto

Albin Sunnanbo Points 30722
var str = "My name @is ,Wan.;'; Wan";
var charsToRemove = new string[] { "@", ",", ".", ";", "'" };
foreach (var c in charsToRemove)
{
    str = str.Replace(c, string.Empty);
}

Mais je peux suggérer une autre approche si vous voulez supprimer tous les caractères non alphabétiques.

var str = "My name @is ,Wan.;'; Wan";
str = new string((from c in str
                  where char.IsWhiteSpace(c) || char.IsLetterOrDigit(c)
                  select c
       ).ToArray());

13 votes

On peut également procéder comme suit : str = new string(str.Where(x=>char.IsWhiteSpace(x)||char.IsLetterOrDigit(x)).ToArray()) ;

1 votes

J'ai dû vérifier, string.Empty ne crée pas de chaîne pour la comparaison, c'est donc plus efficace que "". ( stackoverflow.com/questions/151472/ )

7 votes

Suis-je le seul à obtenir "Argument 2 : cannot convert from 'string' to 'char'" om string.Empty ?

84voto

Enigmativity Points 26345

Simple :

String.Join("", "My name @is ,Wan.;'; Wan".Split('@', ',' ,'.' ,';', '\''));

71voto

John Melville Points 1140

Cela ressemble à une application idéale pour RegEx - un moteur conçu pour la manipulation rapide de texte. Dans ce cas :

Regex.Replace("He\"ll,o Wo'r.ld", "[@,\\.\";'\\\\]", string.Empty)

3 votes

Il semble que cela serait beaucoup plus efficace qu'une approche basée sur les itérateurs, surtout si vous pouvez utiliser une Regex compilée ;

0 votes

Cela devrait être la réponse acceptée, en particulier parce que, comme @AdeMiller l'a dit, ce sera beaucoup plus efficace.

23 votes

Ce n'est pas plus rapide que la boucle, c'est une idée fausse commune que les regex sont toujours plus rapides que les boucles. Les regex ne sont pas magiques, à la base elles doivent à un moment donné itérer dans la chaîne de caractères pour effectuer leurs opérations, et elles peuvent être beaucoup plus lentes avec les surcharges de la regex elle-même. Elles excellent vraiment lorsqu'il s'agit de manipulations extrêmement complexes, où des dizaines de lignes de code et de multiples boucles seraient nécessaires. En testant la version compilée de cette regex contre une simple boucle non optimisée 50000 fois, la regex est 6X plus lente.

39voto

drzaus Points 3344

Comparaison de différentes suggestions (ainsi que comparaison dans le cadre de remplacements d'un seul caractère avec différentes tailles et positions de la cible).

Dans ce cas particulier, la division sur les cibles et la jointure sur les remplacements (dans ce cas, la chaîne vide) est la plus rapide par un facteur d'au moins 3. En fin de compte, les performances sont différentes selon le nombre de remplacements, l'emplacement des remplacements dans la source et la taille de la source. #ymmv

Résultats

(résultats complets ici )

| Test                      | Compare | Elapsed                                                            |
|---------------------------|---------|--------------------------------------------------------------------|
| SplitJoin                 | 1.00x   | 29023 ticks elapsed (2.9023 ms) [in 10K reps, 0.00029023 ms per]   |
| Replace                   | 2.77x   | 80295 ticks elapsed (8.0295 ms) [in 10K reps, 0.00080295 ms per]   |
| RegexCompiled             | 5.27x   | 152869 ticks elapsed (15.2869 ms) [in 10K reps, 0.00152869 ms per] |
| LinqSplit                 | 5.43x   | 157580 ticks elapsed (15.758 ms) [in 10K reps, 0.0015758 ms per]   |
| Regex, Uncompiled         | 5.85x   | 169667 ticks elapsed (16.9667 ms) [in 10K reps, 0.00169667 ms per] |
| Regex                     | 6.81x   | 197551 ticks elapsed (19.7551 ms) [in 10K reps, 0.00197551 ms per] |
| RegexCompiled Insensitive | 7.33x   | 212789 ticks elapsed (21.2789 ms) [in 10K reps, 0.00212789 ms per] |
| Regex Insentive           | 7.52x   | 218164 ticks elapsed (21.8164 ms) [in 10K reps, 0.00218164 ms per] |

Harnais de test (LinqPad)

(remarque : le Perf et Vs sont les extensions de temps que j'ai écrites )

void test(string title, string sample, string target, string replacement) {
    var targets = target.ToCharArray();

    var tox = "[" + target + "]";
    var x = new Regex(tox);
    var xc = new Regex(tox, RegexOptions.Compiled);
    var xci = new Regex(tox, RegexOptions.Compiled | RegexOptions.IgnoreCase);

    // no, don't dump the results
    var p = new Perf/*<string>*/();
        p.Add(string.Join(" ", title, "Replace"), n => targets.Aggregate(sample, (res, curr) => res.Replace(new string(curr, 1), replacement)));
        p.Add(string.Join(" ", title, "SplitJoin"), n => String.Join(replacement, sample.Split(targets)));
        p.Add(string.Join(" ", title, "LinqSplit"), n => String.Concat(sample.Select(c => targets.Contains(c) ? replacement : new string(c, 1))));
        p.Add(string.Join(" ", title, "Regex"), n => Regex.Replace(sample, tox, replacement));
        p.Add(string.Join(" ", title, "Regex Insentive"), n => Regex.Replace(sample, tox, replacement, RegexOptions.IgnoreCase));
        p.Add(string.Join(" ", title, "Regex, Uncompiled"), n => x.Replace(sample, replacement));
        p.Add(string.Join(" ", title, "RegexCompiled"), n => xc.Replace(sample, replacement));
        p.Add(string.Join(" ", title, "RegexCompiled Insensitive"), n => xci.Replace(sample, replacement));

    var trunc = 40;
    var header = sample.Length > trunc ? sample.Substring(0, trunc) + "..." : sample;

    p.Vs(header);
}

void Main()
{
    // also see https://stackoverflow.com/questions/7411438/remove-characters-from-c-sharp-string

    "Control".Perf(n => { var s = "*"; });

    var text = "My name @is ,Wan.;'; Wan";
    var clean = new[] { '@', ',', '.', ';', '\'' };

    test("stackoverflow", text, string.Concat(clean), string.Empty);

    var target = "o";
    var f = "x";
    var replacement = "1";

    var fillers = new Dictionary<string, string> {
        { "short", new String(f[0], 10) },
        { "med", new String(f[0], 300) },
        { "long", new String(f[0], 1000) },
        { "huge", new String(f[0], 10000) }
    };

    var formats = new Dictionary<string, string> {
        { "start", "{0}{1}{1}" },
        { "middle", "{1}{0}{1}" },
        { "end", "{1}{1}{0}" }
    };

    foreach(var filler in fillers)
    foreach(var format in formats) {
        var title = string.Join("-", filler.Key, format.Key);
        var sample = string.Format(format.Value, target, filler.Value);

        test(title, sample, target, replacement);
    }
}

2 votes

Enfin des chiffres ! Bon travail @drzaus !

25voto

ThisClark Points 22

De manière moins spécifique à votre question, il est possible de supprimer TOUTE la ponctuation d'une chaîne (sauf l'espace) en mettant en liste blanche les caractères acceptables dans une expression régulière :

string dirty = "My name @is ,Wan.;'; Wan";

// only space, capital A-Z, lowercase a-z, and digits 0-9 are allowed in the string
string clean = Regex.Replace(dirty, "[^A-Za-z0-9 ]", "");

Notez qu'il y a un espace après le 9 afin de ne pas supprimer les espaces de votre phrase. Le troisième argument est une chaîne vide qui sert à remplacer toute sous-chaîne qui n'appartient pas à l'expression régulière.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X