English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Ruby 字符串(String)

L'objet String en Ruby est utilisé pour stocker ou manipuler une séquence d'un ou plusieurs octets.

Les chaînes en Ruby sont divisées en chaînes entre guillemets simples ('') et chaînes entre guillemets doubles ("), la différence étant que les chaînes entre guillemets doubles peuvent gérer plus de caractères d'échappement.

Chaîne entre guillemets simples

Le type de chaîne le plus simple est la chaîne entre guillemets simples, c'est-à-dire que la chaîne est placée entre des guillemets simples :

'Ceci est une chaîne de programme Ruby'

Si vous avez besoin d'utiliser un guillemet simple dans une chaîne entre guillemets simples, vous devez utiliser un backlash (\) dans la chaîne entre guillemets simples, de sorte que l'interpréteur Ruby ne considère pas ce guillemet simple comme le symbole de fin de chaîne :

'Won't you read O'Reilly's book?'

Le backlash peut également échapper à un autre backlash, de sorte que le deuxième backlash n'est pas interprété comme un caractère d'échappement.

Voici les caractéristiques associées aux chaînes dans Ruby.

Chaîne entre guillemets doubles

Dans une chaîne entre guillemets doubles, nous pouvons utiliser : #{} Le symbole '#' et les accolades pour calculer la valeur d'une expression :

Insertion de variables dans une chaîne :

Exemple en ligne

#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
 
name1 ="Joe"
name2 ="Mary"
puts "Bonjour #{name1}, #{name2}" où est?

Les exemples ci-dessus affichent les résultats de la sortie :

Bonjour Joe, où est Mary?

Opérations mathématiques dans une chaîne :

Exemple en ligne

#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
 
x, y, z = 12, 36, 72
puts "La valeur de 'x' est de #{x"
puts "x + La valeur de 'y' est de #{x + y"
puts "x + y + La moyenne de 'z' est de #{(x + y + z)/3 "}

Les exemples ci-dessus affichent les résultats de la sortie :

La valeur de x est 12
x + La valeur de y est 48
x + y + La moyenne de z est 40

Ruby prend également en charge un type de variable de chaîne de caractères guidée par %q et %Q, %q utilise les règles de citation avec des guillemets simples, et %Q utilise les règles de citation avec des guillemets doubles, suivies d'un début de délimiteur (! [ { etc. et d'un délimiteur de fin ( } ] ) etc.

Les caractères qui suivent q ou Q sont des délimiteurs. Un délimiteur peut être n'importe quel caractère non alphabétique d'un octet. Par exemple : [,{,(,<,! etc., la chaîne est lue jusqu'à ce que le délimiteur de fin correspondant soit trouvé.

Exemple en ligne

#!/usr/bin/ruby
# -*- coding: UTF-8 -*-
 
desc1 = %Q{Ruby de chaînes de caractères peuvent utiliser '' et ""}.
desc2 = %q|Ruby de chaînes de caractères peuvent utiliser '' et "".|
 
puts desc1
puts desc2

Les exemples ci-dessus affichent les résultats de la sortie :

Les chaînes de caractères de Ruby peuvent utiliser '' et "".
Les chaînes de caractères de Ruby peuvent utiliser '' et "".

Caractères d'échappement

Le tableau ci-dessous liste les caractères ou les caractères non imprimables qui peuvent être échappés avec le symbole d'échappement.

Attention :Dans une chaîne entre guillemets doubles, le caractère d'échappement est interprété. Dans une chaîne entre guillemets simples, le caractère d'échappement n'est pas interprété et est affiché tel quel.

Caractère d'échappementCaractère hexadécimalDescription
\a0x07Signal d'alarme
\b0x08Touche d'effacement
\cx Contrôle-x
\C-x Contrôle-x
\e0x1bCaractère d'échappement
\f0x0cRetour à la page
\M-\C-x Méta-Contrôle-x
\n0x0aRetour à la ligne
\nnn Représentation octale, où n varie de 0.7
\r0x0dRetour chariot
\s0x20Espace
\t0x09Tabulation
\v0x0bTabulation verticale
\x Caractère x
\xnn Représentation hexadécimale, où n varie de 0.9、 a.f ou A.F

Encodage de caractères

Le jeu de caractères par défaut de Ruby est ASCII, où les caractères peuvent être représentés par un seul octet. Si vous utilisez UTF-8 ou d'autres jeux de caractères modernes, où les caractères peuvent être représentés par un à quatre octets.

Vous pouvez utiliser $KCODE au début du programme, comme suit :

$KCODE = 'u'

Voici les valeurs possibles de $KCODE.

EncodageDescription
aASCII (identique à none). C'est le défaut.
eEUC。
nNone (identique à ASCII).
uUTF-8.

Méthodes intégrées de chaîne

Nous devons avoir un exemple d'objet String pour appeler les méthodes String. Voici comment créer un exemple d'objet String :

new [String.new(str="")]

Cela retournera un contenant str Nouvel objet de chaîne de caractères. Maintenant, utilisez str Les objets, nous pouvons appeler n'importe quelle méthode d'exemple disponible. Par exemple :

Exemple en ligne

#!/usr/bin/ruby
 
myStr = String.new("THIS IS TEST")
foo = myStr.downcase
 
puts "#{foo}"

Ce qui produit le résultat suivant :

this is test

Voici les méthodes de chaîne publiques (hypothèse que str est un objet String) :

NuméroMéthode & Description
1str % arg
Formater une chaîne de caractères en utilisant des spécifications de format. Si arg contient une ou plusieurs substitutions, alors arg doit être un tableau. Pour plus d'informations sur les spécifications de format, voir "Module noyau" sous sprintf.
2str * integer
Retourne une nouvelle chaîne contenant integer str. Autrement dit, str est répété integer fois.
3str + other_str
Connecte other_str à str.
4str << obj
Connecter un objet à une chaîne. Si l'objet est de la gamme 0.255 Si Fixnum est entre les nombres fixes, il est converti en un caractère. Comparez-le avec concat.
5str <=> other_str
Comparaison de str avec other_str, retourne -1(inférieur)、0(égal)ou 1(supérieur)。La comparaison est sensible à la casse.
6str == obj
Vérifier l'égalité entre str et obj. Si obj n'est pas une chaîne, retourne false, si str <=> obj, retourne true, retourne 0.
7str =~ obj
Correspondre à la pattern régulière obj dans str. Retourne la position de début du match, sinon retourne false.
8str[position] # Le retour est l'ASCII code et non le caractère
str[start, length]
str[start..end]
str[start...end]

Couper une sous-chaîne en utilisant un index.
9str.capitalize
Afficher la chaîne en majuscules.
10str.capitalize!
Comme capitalize, mais str change et retourne.
11str.casecmp
Comparaison de chaînes de caractères sans distinction de cas.
12str.center
Centrer une chaîne de caractères.
13str.chomp
Retirer le séparateur de ligne en fin de chaîne (/),généralement \n. Si le séparateur de ligne n'est pas enregistré, aucune action n'est effectuée.
14str.chomp!
Comme chomp, mais str change et retourne.
15str.chop
Supprime le dernier caractère de str.
16str.chop!
Est égal à chop, mais str est modifié et retourné.
17str.concat(other_str)
Connecte other_str à str.
18str.count(str, ...)
Compte un ou plusieurs ensembles de caractères. Si plusieurs ensembles de caractères sont fournis, il compte l'intersection de ces ensembles.
19str.crypt(other_str)
Applique un hachage cryptographique unidirectionnel à str. Le paramètre est une chaîne de caractères de deux caractères, chaque caractère ayant une plage de a.z, A.Z, 0.9、 . Ou /.
20str.delete(other_str, ...)
Retourne une copie de str où tous les caractères dans l'intersection des paramètres sont supprimés.
21str.delete!(other_str, ...)
Est égal à delete, mais str est modifié et retourné.
22str.downcase
Retourne une copie de str où toutes les lettres majuscules sont remplacées par des lettres minuscules.
23str.downcase!
Est égal à downcase, mais str est modifié et retourné.
24str.dump
Retourne une version de str où tous les caractères non imprimables sont remplacés par le symbole \nnn, et tous les caractères spéciaux sont escapés.
25str.each(separator=$/) { |substr| block }
Utilisez les paramètres en tant que délimiteurs de enregistrement (par défaut est $/) sépare str, et passe chaque sous-chaine au block fourni.
26str.each_byte { |fixnum| block }
Passe chaque byte de str au block, et retourne chaque byte en représentation décimale des bytes.
27str.each_line(separator=$/) { |substr| block }
Utilisez les paramètres en tant que délimiteurs de enregistrement (par défaut est $/) sépare str, et passe chaque sous-chaine au block fourni.
28str.empty?
Si str est vide (c'est-à-dire que la longueur est 0), alors retourne true.
29str.eql?(other)
Si deux chaînes de caractères ont la même longueur et le même contenu, alors ces deux chaînes de caractères sont égales.
30str.gsub(pattern, replacement) [ou]
str.gsub(pattern) { |match| block }

Retourne une copie de str, où toutes les occurrences du pattern sont remplacées par la valeur de replacement ou de block. Le pattern est généralement une expression régulière Regexp ; si c'est une chaîne de caractères String, les caractères de métacaractère de l'expression régulière ne sont pas interprétés (c'est-à-dire,/\d/ Correspond à un nombre, mais '\d' correspond à une barre oblique inversée suivie d'un 'd').
31str[fixnum] [ou] str[fixnum,fixnum] [ou] str[range] [ou] str[regexp] [ou] str[regexp, fixnum] [ou] str[other_str]
Utilisez les paramètres suivants pour faire référence à str : un Fixnum en tant que paramètre retourne le code de caractère du Fixnum ; deux Fixnum en tant que paramètres retourne un sous-chaîne allant du décalage (le premier Fixnum) jusqu'à la longueur (le deuxième Fixnum) ; un range en tant que paramètre retourne un sous-chaîne dans cette plage ; un regexp en tant que paramètre retourne une partie correspondante de la chaîne ; un regexp avec un Fixnum en tant que paramètre retourne les données correspondantes à la position Fixnum ; un other_str en tant que paramètre retourne un sous-chaîne correspondant à other_str. Un Fixnum négatif commence à partir de la fin de la chaîne -1 Commencer.
32str[fixnum] = fixnum [ou] str[fixnum] = new_str [ou] str[fixnum, fixnum] = new_str [ou] str[range] = aString [ou] str[regexp] =new_str [ou] str[regexp, fixnum] =new_str [ou] str[other_str] = new_str ]
Remplace toute la chaîne ou une partie de la chaîne. Synonyme de slice!.
33str.gsub!(pattern, replacement) [ou] str.gsub!(pattern) { |match| block }
Exécute le remplacement de String#gsub, retourne str, et retourne nil si aucune substitution n'est effectuée.
34str.hash
Retourne un hachage basé sur la longueur et le contenu de la chaîne.
35str.hex
Prend les caractères en tête de la chaîne str comme une chaîne de nombres hexadécimaux (un symbole optionnel et un 0x optionnel), et retourne le nombre correspondant. Si une erreur se produit, retourne zéro.
36str.include? other_str [ou] str.include? fixnum
Si la chaîne str contient la chaîne ou le caractère donné, retourne true.
37str.index(sous-chaîne [, offset]) [ou]
str.index(fixnum [, offset]) [ou]
str.index(regexp [, offset])

Retourner l'indice de la première apparition du sous-chaîne, du caractère (fixnum) ou du motif (regexp) dans str. Retourner nil si il n'est pas trouvé. Si le deuxième paramètre est fourni, spécifie la position de début de la recherche dans la chaîne de caractères.
38str.insert(index, other_str)
Insérer other_str avant le caractère à l'indice donné, modifier str. Un indice négatif commence à compter à partir de la fin de la chaîne de caractères, et insère après le caractère donné. L'intention est d'insérer une chaîne de caractères à l'indice donné.
39str.inspect
Retourner la version imprimable de str, avec des caractères spéciaux d'échappement.
40str.intern [ou] str.to_sym
Retourner le symbole correspondant à str, le créer si il n'existe pas.
41str.length
Retourner la longueur de str. La comparer avec size.
42str.ljust(integer, padstr=' ')
Si l'integer est supérieur à la longueur de str, retourner une nouvelle chaîne de caractères de longueur integer, alignée à gauche avec str et remplie avec padstr. Sinon, retourner str.
43str.lstrip
Retourner une copie de str, en enlevant les espaces avant-gardes.
44str.lstrip!
Enlever les espaces avant-gardes de str, retourner nil si il n'y a pas de changement.
45str.match(pattern)
Si le pattern n'est pas une expression régulière, convertir pattern en expression régulière Regexp, puis appeler sa méthode de correspondance sur str.
46str.oct
Prendre les caractères initiaux de str comme une chaîne de caractères de nombre décimal (un symbole optionnel), et retourner le nombre correspondant. Si la conversion échoue, retournera 0.
47str.replace(other_str)
Remplacer le contenu de str par les valeurs correspondantes de other_str.
48str.reverse
Retourner une nouvelle chaîne de caractères, qui est l'inverse de str.
49str.reverse!
Inverser str, str changera et retournera.
50str.rindex(sous-chaîne [, fixnum]) [ou]
str.rindex(fixnum [, fixnum]) [ou]
str.rindex(regexp [, fixnum])

Retourne l'index de la dernière apparition d'un sous-chaîne, d'un caractère (fixnum) ou d'un pattern (regexp) dans str. Si il n'est pas trouvé, retourne nil. Si un deuxième paramètre est fourni, il spécifie la position de fin de la recherche dans la chaîne. Les caractères au-delà de ce point ne sont pas considérés.
51str.rjust(integer, padstr=' ')
Si l'integer est supérieur à la longueur de str, retourne une nouvelle chaîne de longueur integer, alignée à droite avec str et remplie avec padstr. Sinon, retourne str.
52str.rstrip
Retourne une copie de str avec les espaces en fin de chaîne supprimés.
53str.rstrip!
Supprime les espaces en fin de chaîne de str, et retourne nil si il n'y a pas de changement.
54str.scan(pattern) [ou]
str.scan(pattern) { |match, ...| block }

Deux formes de pattern (peut être un Regexp ou une chaîne String) parcourant str. Pour chaque correspondance, un résultat est généré, ajouté à l'array de résultats ou transmis au block. Si le pattern ne contient pas de groupes, chaque résultat indépendant est composé de la chaîne correspondante et de $&. Si le pattern contient des groupes, chaque résultat indépendant est un tableau contenant chaque entrée de groupe.
55str.slice(fixnum) [ou] str.slice(fixnum, fixnum) [ou]
str.slice(range) [ou] str.slice(regexp) [ou]
str.slice(regexp, fixnum) [ou] str.slice(other_str)
Voir str[fixnum], etc.
str.slice!(fixnum) [ou] str.slice!(fixnum, fixnum) [ou] str.slice!(range) [ou] str.slice!(regexp) [ou] str.slice!(other_str)

Supprime une partie spécifiée de la chaîne et renvoie la partie supprimée. Si la valeur dépasse la gamme, une IndexError est générée lorsque le paramètre prend la forme d'un Fixnum. Une RangeError est générée si le paramètre prend la forme d'un range, et l'action est ignorée si le paramètre prend la forme d'un Regexp ou d'une chaîne String.
56str.split(pattern=$;, [limit])

Divise str en sous-chaînes en fonction du séparateur, et retourne un tableau de ces sous-chaînes.

Si pattern Est une chaîne de caractères String, alors il est utilisé comme séparateur lors de la division de str. Si pattern est un espace unique, str est divisé sur la base de l'espace, en ignorer les espaces en tête et les caractères d'espace continu.

Si pattern  Est une expression régulière Regexp, alors str est divisé au niveau de la correspondance de pattern. Lorsque pattern correspond à une chaîne de caractères de longueur zéro, str est divisé en caractères individuels.

Si le paramètre est omis pattern La valeur de $; est utilisée. Si $; est nil (par défaut), str est divisé sur la base de l'espace, comme si ` ` avait été spécifié comme séparateur.

Si le paramètre est omis limit Paramètre, supprime les champs null en queue. Si limit est un nombre positif, il retourne le nombre maximum de champs (si limit est 1Retourne l'ensemble de la chaîne de caractères en tant qu'entrée unique dans le tableau). Si limit est un nombre négatif, le nombre de champs retournés n'est pas limité et les champs null en queue ne sont pas supprimés.

57str.squeeze([other_str]*)
Utilise le programme décrit pour String#count pour construire une série de caractères à partir du paramètre other_str. Retourne une nouvelle chaîne de caractères où les caractères identiques de l'ensemble sont remplacés par un seul caractère. Si aucun paramètre n'est fourni, tous les caractères identiques sont remplacés par un seul caractère.
58str.squeeze!([other_str]*)
Comme squeeze, mais str change et est retourné, et retourne nil si il n'y a pas de changement.
59str.strip
Retourne une copie de str, en supprimant les espaces en tête et en queue.
60str.strip!
Retire les espaces en tête et en queue de str, et retourne nil si il n'y a pas de changement.
61str.sub(pattern, replacement) [ou]
str.sub(pattern) { |match| block }

Retourne une copie de str, où la première occurrence de pattern sera remplacée par replacement ou la valeur de block. pattern est généralement une expression régulière Regexp ; si c'est une chaîne de caractères String, aucun caractère de métamot de l'expression régulière n'est interprété.
62str.sub!(pattern, replacement) [ou]
str.sub!(pattern) { |match| block }

Exécute String#sub pour le remplacement, et retourne str, sinon nil est retourné si il n'y a pas de remplacement.
63str.succ [ou] str.next
Retourne l'héritage de str.
64str.succ! [ou] str.next!
Équivalent à String#succ, mais str change et est retourné.
65str.sum(n=16)
Retourne le n-somme de bits, où n est un paramètre Fixnum optionnel, par défaut de 16Le résultat est simplement la somme des valeurs binaires de chaque caractère de str, avec 2n - 1 mod. Ce n'est pas un bon hachage en particulier.
66str.swapcase
Retourne une copie de str, où toutes les lettres majuscules sont converties en minuscules et toutes les lettres minuscules sont converties en majuscules.
67str.swapcase!
Équivalent à String#swapcase, mais str change et est retourné, sinon nil est retourné si il n'y a pas de changement.
68str.to_f
Retourne l'interprétation des caractères initiaux de str comme un nombre flottant. Les caractères supplémentaires en fin de nombre valide sont ignorés. Si il n'y a pas de nombre valide au début de str, 0.0 est retourné. Cette méthode ne génère pas d'exception.
69str.to_i(base=10)
Retourne l'interprétation des caractères initiaux de str comme une base de nombre (base de 2et 8et 10 ou 16Le résultat. Les caractères supplémentaires en fin de nombre valide sont ignorés. Si il n'y a pas de nombre valide au début de str, 0 est retourné. Cette méthode ne génère pas d'exception.
70str.to_s [ou] str.to_str
Retourne la valeur reçue.
71str.tr(from_str, to_str)
Retourne une copie de str, en remplaçant les caractères de from_str par ceux de to_str correspondants. Si to_str est plus court que from_str, il est rempli avec le dernier caractère. Les deux chaînes peuvent utiliser c1.c2 Le symbole représente la gamme de caractères. Si from_str commence par ^, cela signifie tous les caractères sauf ceux énumérés.
72str.tr!(from_str, to_str)
Équivalent à String#tr, mais str change et est retourné, sinon nil est retourné si il n'y a pas de changement.
73str.tr_s(from_str, to_str)
Traitez str selon les règles décrites par String#tr, puis retirez les caractères répétés qui pourraient affecter la traduction.
74str.tr_s!(from_str, to_str)
Est équivalent à String#tr_s, mais str est modifié et retourné, et retourne nil s'il n'y a pas de changement.
75str.unpack(format)
Décode str (peut contenir des données binaires) en fonction de la chaîne de format, et retourne un tableau avec chaque valeur extraite. La chaîne de format est composée d'une série d'instructions de caractères simples. Une lettre peut être suivie d'un nombre, indiquant le nombre de fois que l'instruction doit être répétée. L'astérisque (*)Utilisera tous les éléments restants. L'instruction sSiIlL peut être suivie d'un underscore (_) après chaque lettre, pour utiliser la taille de base du platforme pour le type spécifié, sinon utiliser une taille cohérente indépendante de la plateforme. Les espaces dans la chaîne de format seront ignorés.
76str.upcase
Retourner une copie de str où toutes les lettres minuscules seront remplacées par des lettres majuscules. L'opération est insensible à l'environnement, seule les lettres a à z sont affectées.
77str.upcase!
Changer le contenu de str en majuscules, et retourner nil si il n'y a pas de changement.
78str.upto(other_str) { |s| block }
Parcourir les valeurs consécutives, à partir de str, jusqu'à other_str (inclus), en passant alternativement chaque valeur au block. La méthode String#succ est utilisée pour générer chaque valeur.

Instructions de dépaquetage des chaînes de caractères

Le tableau suivant liste les instructions de décompression de la méthode String#unpack.

InstructionRetournerDescription
AChaîneSupprimer les nulls et les espaces en fin de chaîne.
aChaîneChaîne de caractères.
BChaîneExtraire un bit de chaque caractère (le premier étant le bit le plus significatif).
bChaîneExtraire un bit de chaque caractère (le premier étant le bit le moins significatif).
CFixnumExtraire un caractère en tant qu'entier sans signe.
cFixnumExtraire un caractère en tant qu'entier.
D, dFloatConsidère les caractères de la longueur sizeof(double) comme des doubles natifs.
EFloatConsidère les caractères de la longueur sizeof(double) comme des doubles en ordre des octets littleendian.
eFloatConsidère les caractères de la longueur sizeof(float) comme des floats en ordre des octets littleendian.
F, fFloatConsidère les caractères de la longueur sizeof(float) comme des floats natifs.
GFloatConsidère les caractères de la longueur sizeof(double) comme des doubles en ordre des octets réseau.
gFloatConsidère les caractères de la longueur sizeof(float) comme des floats en ordre des octets réseau.
HChaîneExtraire l'hexadécimal de chaque caractère (d'abord le bit le plus significatif).
hChaîneExtraire l'hexadécimal de chaque caractère (d'abord le bit le moins significatif).
IEntierPrendre des caractères de longueur sizeof(int) (modifiés par _) adjacents comme integer natif.
iEntierPrendre des caractères de longueur sizeof(int) (modifiés par _) adjacents comme integer natif signé.
LEntierPrendre quatre (modifiés par _) caractères adjacents comme long integer natif unsigned.
lEntierPrendre quatre (modifiés par _) caractères adjacents comme long integer natif signé.
MChaîneCitation imprimable.
mChaîneBase64 Encodage.
NEntierPrendre quatre caractères comme long unsigned en ordre des octets réseau.
nFixnumPrendre deux caractères comme short unsigned en ordre des octets réseau.
PChaîne) caractères de longueur comme un pointeur, et retourner \emph{len} caractères à partir de la position de référence. *) caractères de longueur comme un pointeur, et retourner \emph{len} caractères à partir de la position de référence.
pChaîne) caractères de longueur comme un pointeur, et retourner \emph{len} caractères à partir de la position de référence. *Prendre sizeof(char
) caractères de longueur comme un pointeur de fin de chaîne null.EntierPrendre huit caractères comme quad word unsigned (64 Bits).
qEntierPrendre huit caractères comme quad word signé (64 Bits).
SFixnumPrendre deux (si _ est utilisé, différent) caractères adjacents comme short unsigned en ordre des octets natif.
sFixnumPrendre deux (si _ est utilisé, différent) caractères adjacents comme short signé en ordre des octets natif.
UEntierUTF-8 Caractère, comme entier unsigned.
uChaîneEncodage UU.
VFixnumPrendre quatre caractères comme little-Long unsigned en ordre des octets endian.
vFixnumPrendre deux caractères comme little-Short unsigned en ordre des octets endian.
wEntierEntier compressé BER.
X Passer un caractère en arrière.
x Passer un caractère en avant.
ZChaîneEt * Utilisés ensemble, supprimer les null en fin jusqu'au premier null.
@ Ignorer la quantité d'offset spécifiée par le paramètre length.

Exemple en ligne

Essayer l'exemple suivant, décompresser divers types de données.

"abc \0\0abc \0\0".unpack('A6Z6#=> ["abc", "abc "]
"abc \0\0".unpack('a3a3#=> ["abc", " \000\000"]
"abc \0abc \0".unpack('Z')*Z*
"aa".unpack('b')8B810000110", "01100001"]
"aaa".unpack('h')2H2c') => ["16", "61" 97]
"\xfe\xff\xfe\xff".unpack('sS') => [-2, 65534]
"now="20is".unpack('M')*
"whole".unpack('xax') => ["now is"]2aX2aX1aX2a') => ["h", "e", "l", "l", "o"]