Fractionner une chaîne par une autre chaîne en C #

682

J'ai utilisé la Split()méthode pour diviser les chaînes, mais cela ne semble fonctionner que si vous divisez une chaîne par un caractère. Existe-t-il un moyen de diviser a string, une autre chaîne étant le paramètre split by?

J'ai essayé de convertir le séparateur en un tableau de caractères, sans succès.

En d'autres termes, je voudrais diviser le string:

THExxQUICKxxBROWNxxFOX

par xx, et retourne un tableau avec des valeurs:

LE RENARD BRUN RAPIDE

Brandon
la source
2
Pour les préoccupations futures: l'un des commentaires ci-dessous m'a intéressé, j'ai donc décidé d'ouvrir une discussion sur l'ingénierie logicielle concernant la manière non intuitive (mais correcte) de le faire dans la réponse acceptée.
scharette

Réponses:

1239

Afin de diviser par une chaîne, vous devrez utiliser la surcharge du tableau de chaînes .

string data = "THExxQUICKxxBROWNxxFOX";

return data.Split(new string[] { "xx" }, StringSplitOptions.None);
Adam Robinson
la source
4
En fait, j'ai fini par changer ma réponse à cela pour 2 raisons: # 1: Pour gérer les divisions que je veux faire, je devrais utiliser Regex.Escape, car ma chaîne de fractionnement contiendra souvent des astérisques, etc. # 2: Bien que ce programme J'écris n'a besoin d'aucune optimisation réelle, il semble y avoir des frais supplémentaires liés à l'utilisation de la méthode Regex Split.
Brandon
7
@Peter: Dans ce post, Jon le suggère parce que l'affiche n'a pas de délimiteur fixe; il cherche à séparer les chaînes séparées par "plus d'un espace" (c'est-à-dire 2+). Pour les chaînes délimitées par un motif plutôt que par une valeur , RegEx est une excellente (enfin, la seule ) option. Pour les délimiteurs à valeur fixe, il introduit une surcharge inutile. Essayez d'exécuter un test; au fur et à mesure que le nombre d'opérations augmente, RegEx finit par prendre environ 10 fois plus longtemps qu'un correspondant string.Split.
Adam Robinson
9
Je viens de Python en C #. Python prend en charge la chaîne divisée par une autre chaîne. Et j'ai souvent besoin de revenir à cette question pour une réponse simple string[] Split(string pattern), qui est l'utilisation la plus naturelle à laquelle je pouvais penser, mais elle n'est pas là. J'ai écrit C avant, donc j'ai l'habitude de charger des tableaux, mais je déteste toujours voir char[]apparaître un code C # car cela attire soudainement mon attention du niveau du flux au niveau des octets. Quelqu'un sait pourquoi les gars de la bibliothèque C # ont conçu la méthode Split comme ça? S'il y a une bonne raison, je peux probablement essayer de l'apprécier malgré les inconvénients.
foresightyj
11
Cet extrait de code se classe très haut sur la liste des choses dont j'aurais honte de montrer aux développeurs non C #.
Traubenfuchs
99
Pourquoi diable ne pouvons-nous pas simplement faire data.Split("xx")?
mcont
122

Il y a une surcharge de Split qui prend des chaînes.

"THExxQUICKxxBROWNxxFOX".Split(new [] { "xx" }, StringSplitOptions.None);

Vous pouvez utiliser l'une de ces options StringSplitOptions

  • Aucun - La valeur de retour inclut des éléments de tableau qui contiennent une chaîne vide
  • RemoveEmptyEntries - La valeur de retour n'inclut pas les éléments de tableau qui contiennent une chaîne vide

Donc, si la chaîne est "THExxQUICKxxxxBROWNxxFOX", StringSplitOptions.Noneretournera une entrée vide dans le tableau pour la partie "xxxx" alors que StringSplitOptions.RemoveEmptyEntriesce ne sera pas le cas.

Greg
la source
73
Regex.Split(string, "xx")

est la façon dont je le fais habituellement.


Bien sûr, vous aurez besoin de:

using System.Text.RegularExpressions;

ou :

System.Text.RegularExpressions.Regex.Split(string, "xx")

mais là encore, j'ai besoin de cette bibliothèque tout le temps.

Peter
la source
13
@Brandon: Bien que je mette généralement en garde contre une optimisation prématurée, vous devez savoir qu'un RegEx.Splitest un peu plus coûteux qu'un simple en String.Splitraison de la surcharge des expressions régulières.
Adam Robinson
9
Si vous voulez diviser par une chaîne arbitraire, utilisez Regex.Escaped'abord la chaîne, cela échappera à tous les méta-caractères regex.
Richard
l'un des principaux avantages qui peuvent payer pour les frais généraux est la capacité à fournir un paramètre de comparaison de chaînes
Timur Sadykov
47

Il y a une surcharge de String.Split pour cela:

"THExxQUICKxxBROWNxxFOX".Split(new [] {"xx"}, StringSplitOptions.None);
bruno conde
la source
1
La seule réponse qui supprime la déclaration de type de tableau inutile.
wonea
25

J'aime généralement utiliser ma propre extension pour cela:

string data = "THExxQUICKxxBROWNxxFOX";
var dataspt = data.Split("xx");
//>THE  QUICK  BROWN  FOX 


//the extension class must be declared as static
public static class StringExtension
{   
    public static string[] Split(this string str, string splitter)
    {
        return str.Split(new[] { splitter }, StringSplitOptions.None);
    }
}

Cela entraînera cependant une exception si Microsoft décide d'inclure cette surcharge de méthode dans les versions ultérieures. C'est également la raison probable pour laquelle Microsoft n'a pas inclus cette méthode entre-temps: au moins une entreprise pour laquelle j'ai travaillé a utilisé une telle extension dans tous ses projets C #.

Il peut également être possible de définir conditionnellement la méthode lors de l'exécution si elle n'existe pas.

Lorenz Lo Sauer
la source
4
Vous pouvez également utiliser params string[] splittercomme deuxième paramètre et modifier new[] {splitter}pour splitterprendre en charge plusieurs délimiteurs.
Matthew Strawbridge
10

Les réponses précédentes sont toutes correctes. Je vais un peu plus loin et fais fonctionner C # pour moi en définissant une méthode d'extension sur String:

public static class Extensions
{
    public static string[] Split(this string toSplit, string splitOn) {
        return toSplit.Split(new string[] { splitOn }, StringSplitOptions.None);
    }
}

De cette façon, je peux l'appeler sur n'importe quelle chaîne de la manière simple à laquelle je m'attendais naïvement la première fois que j'ai essayé d'accomplir ceci:

"a big long string with stuff to split on".Split("g str");
argyle
la source
7
string data = "THExxQUICKxxBROWNxxFOX";

return data.Replace("xx","|").Split('|');

Choisissez simplement le caractère de remplacement avec soin (choisissez-en un qui n'est probablement pas déjà présent dans la chaîne)!

Accroc
la source
2
@MasoudHosseini: Veuillez lire la réponse complète; il y a déjà un avertissement.
SNag
3
@kobe: Parce que c'est un terrible hack.
Overv
3
Fonctionne bien, mais il est dangereux pour les méthodes génériques
Kaizonaro
5
Publier des explications comme "C'est un piratage terrible" ou "une mauvaise réponse" ne sont pas utiles. C'est simplement une opinion sans explication. Au lieu de cela, en déclarant quelque chose comme "Il n'est pas nécessaire à la fois d'analyser la chaîne pour les remplacements, puis de rechercher les caractères fractionnés car cela conduit à de mauvaises performances." serait une meilleure façon de vous expliquer. Trop de programmeurs agissent de cette façon. :(
Matt Ruwe
1
Et si la chaîne contient |déjà le caractère, pour cette raison, je pense que c'est dangereux à utiliser.
amd
-1

C'est aussi simple:

string data = "THExxQUICKxxBROWNxxFOX";
string[] arr = data.Split("xx".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
user890255
la source
1
Mais cela se diviserait également "THExQUICK"là où nous ne voulons pas qu'il soit
divisé
Merci Rafalon: oui, Greg est la meilleure réponse: data.Split (nouvelle chaîne [] {"xx"}, StringSplitOptions.RemoveEmptyEntries)
user890255
-4

La façon la plus simple est d'utiliser String.Replace:

string myString = "THExxQUICKxxBROWNxxFOX";
mystring = mystring.Replace("xx", ", ");

Ou plus simplement:

string myString = "THExxQUICKxxBROWNxxFOX".Replace("xx", ", ");
user3458227
la source
3
En l'état, cela ne retournera pas un tableau (comme le demande la question), juste une chaîne avec des virgules où se xxtrouvaient les.
Arj
Et non seulement si la chaîne contenait des virgules supplémentaires, vous ne seriez pas en mesure de fractionner correctement les mots.
user3658298