Fractionnement de chaînes dans Ruby à l'aide de la méthode de partage String #

À moins que l'entrée utilisateur ne soit un seul mot ou nombre, cette entrée devra être divisée ou transformée en une liste de chaînes ou de nombres.

Par exemple, si un programme vous demande votre nom complet, y compris l'initiale du deuxième prénom, il devra d'abord diviser cette entrée en trois chaînes distinctes avant de pouvoir fonctionner avec votre prénom, votre deuxième prénom et votre nom de famille. Ceci est réalisé en utilisant le String # split méthode.

Comment fonctionne String # split

Dans sa forme la plus élémentaire, String # split prend un seul argument: le délimiteur de champ sous forme de chaîne. Ce délimiteur sera supprimé de la sortie et un tableau de chaînes divisé sur le délimiteur sera renvoyé.

Ainsi, dans l'exemple suivant, en supposant que l'utilisateur saisisse correctement son nom, vous devriez recevoir un élément à trois éléments. Array de la scission.

#! / usr / bin / env rubis
imprimer "Quel est votre nom complet?"
full_name = gets.chomp
name = full_name.split (")
met "Votre prénom est # name.first"
met "Votre nom de famille est # name.last"

Si nous exécutons ce programme et saisissons un nom, nous obtiendrons certains résultats attendus. Notez également que name.first et dernier nom sont des coïncidences. le Nom sera une variable Array, et ces deux appels de méthode seront équivalents à nom [0] et nom [-1] respectivement.

$ ruby ​​split.rb
Quel est ton nom complet? Michael C. Morin
Votre prénom est Michael
Votre nom est Morin

pourtant, String # split est un peu plus intelligent que vous ne le pensez. Si l'argument de String # split est une chaîne, il l'utilise en effet comme délimiteur, mais si l'argument est une chaîne avec un seul espace (comme nous l'avons utilisé), il en déduit que vous souhaitez diviser sur n'importe quelle quantité d'espace et que vous souhaitez également supprimer tout espace blanc de premier plan.

Donc, si nous devions lui donner une entrée légèrement malformée comme

Michael C. Morin

(avec des espaces supplémentaires), puis String # split ferait toujours ce qui est attendu. Cependant, c'est le seul cas spécial lorsque vous passez un Chaîne comme premier argument. Délimiteurs d'expression régulière

Vous pouvez également passer une expression régulière comme premier argument. Ici, String # split devient un peu plus flexible. Nous pouvons également rendre notre code de fractionnement de petit nom un peu plus intelligent.

Nous ne voulons pas de la période à la fin de l'initiale du milieu. Nous savons que c'est une initiale au milieu, et la base de données ne voudra pas de période, nous pouvons donc la supprimer pendant que nous nous séparons. Quand String # split correspond à une expression régulière, il fait exactement la même chose que s'il venait de correspondre à un délimiteur de chaîne: il le retire de la sortie et le fractionne à ce point.

Ainsi, nous pouvons faire évoluer un peu notre exemple:

$ cat split.rb
#! / usr / bin / env rubis
imprimer "Quel est votre nom complet?"
full_name = gets.chomp
name = full_name.split (/ \.? \ s + /)
met "Votre prénom est # name.first"
met "Votre initiale du milieu est # name [1]"
met "Votre nom de famille est # name.last"

Séparateur d'enregistrements par défaut

Ruby n'est pas vraiment grand sur les "variables spéciales" que vous pourriez trouver dans des langages comme Perl, mais String # split en utilise un dont vous devez être conscient. Il s'agit de la variable de séparation d'enregistrements par défaut, également appelée $;.

C'est un global, quelque chose que vous ne voyez pas souvent dans Ruby, donc si vous le changez, cela pourrait affecter d'autres parties du code - assurez-vous simplement de le changer à nouveau une fois terminé.

Cependant, tout ce que cette variable fait, c'est agir comme valeur par défaut pour le premier argument de String # split. Par défaut, cette variable semble être définie sur néant. Toutefois, si String # splitLe premier argument de néant, il le remplacera par une seule chaîne d'espace.

Délimiteurs de longueur nulle

Si le délimiteur est passé à String # split est une chaîne de longueur nulle ou une expression régulière, alors String # split agira un peu différemment. Il ne supprimera rien du tout de la chaîne d'origine et se divisera sur chaque caractère. Cela transforme essentiellement la chaîne en un tableau de longueur égale contenant uniquement des chaînes à un caractère, une pour chaque caractère de la chaîne.

Cela peut être utile pour itérer sur la chaîne et a été utilisé dans les versions antérieures à 1.9.x et pré-1.8.7 (qui rétroportait un certain nombre de fonctionnalités à partir de 1.9.x) pour parcourir les caractères d'une chaîne sans se soucier de la rupture de plusieurs octets de caractères Unicode. Cependant, si ce que vous voulez vraiment faire est d'itérer sur une chaîne et que vous utilisez 1.8.7 ou 1.9.x, vous devriez probablement utiliser Chaîne # each_char au lieu.

#! / usr / bin / env rubis
str = "Elle m'a transformé en triton!"
str.split ("). chacun fait | c |
met c
fin

Limiter la longueur du tableau retourné

Revenons donc à notre exemple d'analyse de nom, et si quelqu'un a un espace dans son nom de famille? Par exemple, les noms de famille néerlandais peuvent souvent commencer par "van" (qui signifie "de" ou "de").

Nous ne voulons vraiment qu'un tableau à 3 éléments, nous pouvons donc utiliser le deuxième argument pour String # split que nous avons jusqu'à présent ignoré. Le deuxième argument devrait être un Fixnum. Si cet argument est positif, tout au plus, de nombreux éléments seront remplis dans le tableau. Donc, dans notre cas, nous voudrions passer 3 pour cet argument.

#! / usr / bin / env rubis
imprimer "Quel est votre nom complet?"
full_name = gets.chomp
name = full_name.split (/ \.? \ s + /, 3)
met "Votre prénom est # name.first"
met "Votre initiale du milieu est # name [1]"
met "Votre nom de famille est # name.last"

Si nous l'exécutons à nouveau et lui donnons un nom néerlandais, il agira comme prévu.

$ ruby ​​split.rb
Quel est ton nom complet? Vincent Willem van Gogh
Votre prénom est Vincent
Votre initiale au milieu est Willem
Votre nom de famille est van Gogh

Cependant, si cet argument est négatif (tout nombre négatif), il n'y aura pas de limite sur le nombre d'éléments dans le tableau de sortie et tous les délimiteurs de fin apparaîtront sous la forme de chaînes de longueur nulle à la fin du tableau.

Cela est démontré dans cet extrait IRB:

: 001> "ceci, est, un, test ,,,,". Split (',', -1)
=> ["ceci", "est", "un", "test", "", "", "", ""]