une machine d'état peut facilement le faire, mais c'est probablement exagéré si vous n'en avez besoin que pour supprimer des espaces
Adrian
J'ai ajouté un point de repère sur les différentes façons de le faire dans une question en double stackoverflow.com/a/37592018/582061 . Regex n'était pas le moyen le plus rapide de le faire.
Stian Standahl
Réponses:
469
string sentence ="This is a sentence with multiple spaces";RegexOptions options =RegexOptions.None;Regex regex =newRegex("[ ]{2,}", options);
sentence = regex.Replace(sentence," ");
J'ai copié et collé ça et ça marche. Je n'aime vraiment pas REgex mais cette fois cela me sauve la vie.
Pokus
9
@Craig un commentaire suffirait, OMI. // Ce bloc remplace plusieurs espaces par un ... :)
paulwhit
6
Vraiment, RegEx est exagéré pour cela.
Joel Coehoorn
11
@Joel: Je ne peux pas être d'accord. Je suis en fait sûr que cette méthode est plus efficace que la vôtre pour des chaînes suffisamment grandes et peut être effectuée sur une seule ligne. Où est l'excès?
Konrad Rudolph
24
Le code de @Oscar Joel n'est pas une simple boucle à travers tous les caractères! C'est une boucle imbriquée cachée qui présente le pire cas quadratique. Cette expression régulière, en revanche, est linéaire, ne construit qu'une seule chaîne (= coûts d'allocation considérablement réduits par rapport au code de Joel) et en outre le moteur peut optimiser l'enfer (pour être honnête, je doute que l'expression régulière .NET soit assez intelligent pour cela, mais en théorie, cette expression régulière peut être implémentée à un prix si bas qu'elle n'est même plus drôle; elle n'a besoin que d'un DFA avec trois états, une transition chacun et aucune information supplémentaire).
Konrad Rudolph
624
J'aime utiliser:
myString =Regex.Replace(myString,@"\s+"," ");
Puisqu'il attrapera des courses de n'importe quel genre d'espace blanc (par exemple des tabulations, des nouvelles lignes, etc.) et les remplacera par un espace simple.
Légère modification: Regex.Replace (source, @ "(\ s) \ s +", "$ 1"); Cela renverra le premier type d'espace blanc trouvé. Donc, si vous avez 5 onglets, il renverra un onglet. Au cas où quelqu'un préfère cela.
FB ten Kate
@radistao Votre lien est pour remplacer la chaîne Javascript, pas pour C #.
Shiva
1
@Shiva, / \ s \ s + / est une instruction regex POSIX standard et peut être convertie / utilisée dans n'importe quelle langue en utilisant sa propre syntaxe
radistao
4
Dans l'esprit de la solution de @ FBtenKate: Regex.Replace (source, @ "(\ s) \ 1+", "$ 1"); remplacera plusieurs caractères consécutifs identiques par un seul.
François Beaune
1
afin de supprimer les espaces blancs de début et de fin, vous devez utiliser la fonction Trim () avec ceci ,, comme var myString = Regex.Replace (myString, @ "\ s +", "") .Trim ();
C'est plus lisible que regex, je le préfère plus parce que je n'ai pas besoin d'apprendre une autre syntaxe
Michael Bahig
9
Je l'aime parce qu'il n'a pas besoin de Regex
AleX_
3
Ce serait inefficace pour les grandes chaînes.
DarcyThomas
3
Cela supprime également les espaces de début et de fin.
Matzi
1
Je préfère également cette réponse. Mon ancien mentor disait «chaque fois que vous avez un problème, vous pensez que vous avez besoin de Regex pour le résoudre, eh bien ... maintenant vous avez DEUX problèmes" <clin d'œil>
William Madonna Jr.
38
Je pense que la réponse de Matt est la meilleure, mais je ne pense pas que ce soit tout à fait juste. Si vous souhaitez remplacer les sauts de ligne, vous devez utiliser:
RegexOptions.Multiline change la signification de ^ et $ afin qu'ils correspondent au début et à la fin de chaque ligne ($ = \ n), au lieu de la chaîne multi-lignes entière. Parce que \ s est équivalent à [\ f \ n \ r \ t \ v], les sauts de ligne doivent être remplacés même si l'option Multiligne est désactivée.
SushiGuy
1
La réponse de Matt a déjà couvert cela. Je 'crois' que 30 personnes ont simplement voté les yeux bandés pour cette réponse :)
Ce sera beaucoup moins efficace que l'expression régulière "{2,}" si la chaîne contient des séquences de 3 espaces ou plus.
Jan Goyvaerts
2
@JanGoyvaerts: Même avec 10 espaces, l'expression régulière était plus lente lorsque j'ai fait un test rapide et sale. Cela étant dit, il suffit d'une seule sous-chaîne géante pleine d'espaces pour tuer complètement les performances de la boucle while. Par souci d'équité, j'ai utilisé J'ai utilisé RegexOptions.Compiled, plutôt que le Regex.Replace plus lent.
Brian
5
RegexOptions.Compiled ajoute beaucoup de frais généraux lors de la compilation de l'expression régulière en IL. Ne l'utilisez pas sauf si votre application utilisera l'expression régulière assez souvent ou sur des chaînes suffisamment grandes pour que la vitesse de correspondance accrue compense la vitesse de compilation réduite.
Jan Goyvaerts
Ceci est un exemple de code extrêmement inefficace. LOL.
pcbabu
1
@pcbabu Ce n'est pas aussi mauvais qu'il n'y paraît dans de nombreux cas. La Replace()méthode gérera toutes les occurrences de deux espaces dans une chaîne donnée, donc nous ne bouclons pas (et ne réallouons pas une chaîne entière) pour chaque instance d'espaces appariés dans la chaîne. Une nouvelle allocation les gérera tous. Nous ne réexécutons la boucle que lorsqu'il y avait 3 espaces ou plus ensemble, ce qui est probablement plus rare pour de nombreuses sources d'entrée. Si vous pouvez montrer que cela devient un problème pour vos données, alors écrivez la machine d'état pour pousser caractère par caractère dans un nouveau constructeur de chaînes.
Joel Coehoorn
21
Regex peut être assez lent, même avec des tâches simples. Cela crée une méthode d'extension qui peut être utilisée à partir de n'importe quel string.
publicstaticclassStringExtension{publicstaticStringReduceWhitespace(thisStringvalue){var newString =newStringBuilder();bool previousIsWhitespace =false;for(int i =0; i <value.Length; i++){if(Char.IsWhiteSpace(value[i])){if(previousIsWhitespace){continue;}
previousIsWhitespace =true;}else{
previousIsWhitespace =false;}
newString.Append(value[i]);}return newString.ToString();}}
Il serait utilisé comme tel:
string testValue ="This contains too much whitespace."
testValue = testValue.ReduceWhitespace();// testValue = "This contains too much whitespace."
Pour ceux qui n'aiment pas Regex, voici une méthode qui utilise StringBuilder:
publicstaticstringFilterWhiteSpaces(string input){if(input ==null)returnstring.Empty;StringBuilder stringBuilder =newStringBuilder(input.Length);for(int i =0; i < input.Length; i++){char c = input[i];if(i ==0|| c !=' '||(c ==' '&& input[i -1]!=' '))
stringBuilder.Append(c);}return stringBuilder.ToString();}
Dans mes tests, cette méthode était en moyenne 16 fois plus rapide avec un très grand ensemble de chaînes de petite à moyenne taille, par rapport à une Regex compilée statique. Comparé à une regex non compilée ou non statique, cela devrait être encore plus rapide.
Gardez à l'esprit qu'il ne supprime pas les espaces de début ou de fin, mais uniquement les occurrences multiples de ceux-ci.
Vous devez vous assurer que votre chaîne ne contient pas "()" ou ") (". Ou "wel()come to london)("devient "wel come to london". Vous pouvez essayer d'utiliser beaucoup de crochets. Utilisez donc à la ((((()))))place de ()et à la )))))(((((place de )(. Cela fonctionnera toujours. la chaîne contient ((((()))))ou )))))(((((, cela échouera.
nmit026
7
Il s'agit d'une version plus courte, qui ne doit être utilisée que si vous ne le faites qu'une seule fois, car elle crée une nouvelle instance de la Regex classe à chaque appel.
temp =newRegex(" {2,}").Replace(temp," ");
Si vous n'êtes pas trop familier avec les expressions régulières, voici une courte explication:
le {2,} fait que l'expression régulière recherche le caractère qui le précède et trouve des sous-chaînes entre 2 et un nombre illimité de fois.
Le .Replace(temp, " ")remplace toutes les correspondances dans la chaîne de caractères par un espace.
Si vous souhaitez l'utiliser plusieurs fois, voici une meilleure option, car elle crée l'IL regex au moment de la compilation:
pas de Regex, pas de Linq ... supprime les espaces de début et de fin ainsi que la réduction de tous les segments d'espace intégrés dans un seul espace
Un mot d'avertissement: L'utilisation de la division, bien que très simple à comprendre, peut avoir un impact sur les performances étonnamment négatif. Comme de nombreuses chaînes peuvent être créées, vous devrez surveiller votre utilisation de la mémoire au cas où vous manipuleriez de grandes chaînes avec cette méthode.
Pac0
5
Consolider d'autres réponses, par Joel, et, espérons-le, s'améliorer légèrement au fur et à mesure:
Une des choses intéressantes à ce sujet est qu'il fonctionne avec des collections qui ne sont pas des chaînes, en appelant ToString () sur les éléments. L'utilisation est toujours la même:
//...string s =" 1 2 4 5".Split(" ".ToCharArray(),StringSplitOptions.RemoveEmptyEntries).Join(" ");
pourquoi créer une méthode d'extension? pourquoi ne pas simplement utiliser string.Join ()?
Eric Schoonover
3
// Mysample stringstring str ="hi you are a demo";//Split the words based on white sapcevar demo= str .Split(' ').Where(s =>!string.IsNullOrWhiteSpace(s));//Join the values back and add a single space in between
str =string.Join(" ", demo);//output: string str ="hi you are a demo";
Je sais que c'est assez vieux, mais je l'ai rencontré en essayant d'accomplir presque la même chose. Trouvé cette solution dans RegEx Buddy. Ce modèle remplacera tous les espaces doubles par des espaces simples et coupera également les espaces de début et de fin.
pattern:(?m:^+|+$|(){2,})
replacement: $1
C'est un peu difficile à lire car nous avons affaire à un espace vide, donc ici, c'est à nouveau avec les "espaces" remplacés par un "_".
pattern:(?m:^_+|_+$|(_){2,})<-- don't use this, just for illustration.
La construction "(? M:" active l'option "multiligne". J'aime généralement inclure toutes les options que je peux dans le motif lui-même afin qu'il soit plus autonome.
De nombreuses réponses fournissent la bonne sortie, mais pour ceux qui recherchent les meilleures performances, j'ai amélioré la réponse de Nolanar (qui était la meilleure réponse pour les performances) d'environ 10%.
publicstaticstringMergeSpaces(thisstring str){if(str ==null){returnnull;}else{StringBuilder stringBuilder =newStringBuilder(str.Length);int i =0;foreach(char c in str){if(c !=' '|| i ==0|| str[i -1]!=' ')
stringBuilder.Append(c);
i++;}return stringBuilder.ToString();}}
while word.contains(" ")//double space
word = word.Replace(" "," ");//replace double space by single space.
word = word.trim();//to remove single whitespces from start & end.
using System;
using System.Linq;
using System.Text;publicstaticclassStringExtension{publicstaticstringStripSpaces(thisstring s){return s.Aggregate(newStringBuilder(),(acc, c)=>{if(c !=' '|| acc.Length>0&& acc[acc.Length-1]!=' ')
acc.Append(c);return acc;}).ToString();}publicstaticvoidMain(){Console.WriteLine("\""+StringExtension.StripSpaces("1 Hello World 2 ")+"\"");}}
Réponses:
la source
J'aime utiliser:
Puisqu'il attrapera des courses de n'importe quel genre d'espace blanc (par exemple des tabulations, des nouvelles lignes, etc.) et les remplacera par un espace simple.
la source
la source
Je pense que la réponse de Matt est la meilleure, mais je ne pense pas que ce soit tout à fait juste. Si vous souhaitez remplacer les sauts de ligne, vous devez utiliser:
la source
Une autre approche qui utilise LINQ:
la source
C'est beaucoup plus simple que ça:
la source
Replace()
méthode gérera toutes les occurrences de deux espaces dans une chaîne donnée, donc nous ne bouclons pas (et ne réallouons pas une chaîne entière) pour chaque instance d'espaces appariés dans la chaîne. Une nouvelle allocation les gérera tous. Nous ne réexécutons la boucle que lorsqu'il y avait 3 espaces ou plus ensemble, ce qui est probablement plus rare pour de nombreuses sources d'entrée. Si vous pouvez montrer que cela devient un problème pour vos données, alors écrivez la machine d'état pour pousser caractère par caractère dans un nouveau constructeur de chaînes.Regex peut être assez lent, même avec des tâches simples. Cela crée une méthode d'extension qui peut être utilisée à partir de n'importe quel
string
.Il serait utilisé comme tel:
la source
la source
Pour ceux qui n'aiment pas
Regex
, voici une méthode qui utiliseStringBuilder
:Dans mes tests, cette méthode était en moyenne 16 fois plus rapide avec un très grand ensemble de chaînes de petite à moyenne taille, par rapport à une Regex compilée statique. Comparé à une regex non compilée ou non statique, cela devrait être encore plus rapide.
Gardez à l'esprit qu'il ne supprime pas les espaces de début ou de fin, mais uniquement les occurrences multiples de ceux-ci.
la source
Vous pouvez simplement le faire en une seule solution!
Vous pouvez choisir d'autres parenthèses (ou même d'autres caractères) si vous le souhaitez.
la source
"wel()come to london)("
devient"wel come to london"
. Vous pouvez essayer d'utiliser beaucoup de crochets. Utilisez donc à la((((()))))
place de()
et à la)))))(((((
place de)(
. Cela fonctionnera toujours. la chaîne contient((((()))))
ou)))))(((((
, cela échouera.Il s'agit d'une version plus courte, qui ne doit être utilisée que si vous ne le faites qu'une seule fois, car elle crée une nouvelle instance de la
Regex
classe à chaque appel.Si vous n'êtes pas trop familier avec les expressions régulières, voici une courte explication:
le
{2,}
fait que l'expression régulière recherche le caractère qui le précède et trouve des sous-chaînes entre 2 et un nombre illimité de fois.Le
.Replace(temp, " ")
remplace toutes les correspondances dans la chaîne de caractères par un espace.Si vous souhaitez l'utiliser plusieurs fois, voici une meilleure option, car elle crée l'IL regex au moment de la compilation:
la source
pas de Regex, pas de Linq ... supprime les espaces de début et de fin ainsi que la réduction de tous les segments d'espace intégrés dans un seul espace
résultat: "0 1 2 3 4 5"
la source
Consolider d'autres réponses, par Joel, et, espérons-le, s'améliorer légèrement au fur et à mesure:
Vous pouvez le faire avec
Regex.Replace()
:Ou avec
String.Split()
:la source
Je viens d'écrire une nouvelle
Join
que j'aime, alors j'ai pensé que je répondrais de nouveau avec:Une des choses intéressantes à ce sujet est qu'il fonctionne avec des collections qui ne sont pas des chaînes, en appelant ToString () sur les éléments. L'utilisation est toujours la même:
la source
la source
Je sais que c'est assez vieux, mais je l'ai rencontré en essayant d'accomplir presque la même chose. Trouvé cette solution dans RegEx Buddy. Ce modèle remplacera tous les espaces doubles par des espaces simples et coupera également les espaces de début et de fin.
C'est un peu difficile à lire car nous avons affaire à un espace vide, donc ici, c'est à nouveau avec les "espaces" remplacés par un "_".
La construction "(? M:" active l'option "multiligne". J'aime généralement inclure toutes les options que je peux dans le motif lui-même afin qu'il soit plus autonome.
la source
De nombreuses réponses fournissent la bonne sortie, mais pour ceux qui recherchent les meilleures performances, j'ai amélioré la réponse de Nolanar (qui était la meilleure réponse pour les performances) d'environ 10%.
la source
Je peux supprimer les espaces blancs avec ceci
la source
Utilisez le modèle regex
la source
essayez cette méthode
utilisez-le comme ceci:
la source
Voici une légère modification de la réponse originale de Nolonar .
Pour vérifier si le caractère n'est pas seulement un espace, mais n'importe quel espace, utilisez ceci:
Il remplacera tout caractère d'espaces multiples par un seul espace.
la source
Vieille école:
la source
Sans utiliser d'expressions régulières:
OK à utiliser sur les chaînes courtes, mais fonctionne mal sur les chaînes longues avec beaucoup d'espace.
la source
Mélange de StringBuilder et Enumerable.Aggregate () comme méthode d'extension pour les chaînes:
Contribution:
Production:
la source