Implémentation
Les fonctions ci-dessous permettront d'insérer une chaîne dans une autre chaîne :
def str_insert(from_me, into_me, at):
"""
Insère la chaîne dans
L'entrée doit être un index entier de ou une sous-chaîne de
Insère APRÈS , pas avant
Les entrées et doivent avoir des méthodes __str__ définies.
Cela est satisfait s'ils sont déjà des chaînes.
Si ce ne sont pas déjà des chaînes, , sont convertis en chaînes.
Si vous essayez d'insérer une chaîne vide, c'est bien, et le résultat
n'est pas différent de l'original.
Pour insérer 'from_me' après rien (insérer au début de la chaîne) utilisez :
at = '' ou at = 0
"""
try:
return str_insert_or_raise(from_me, into_me, at)
except ValueError as err:
serr = str(err)
if (str_insert_or_raise.__name__ in serr) and 'non trouvé' in serr and '' in serr:
# si on ne peut pas trouver où insérer quelque chose, ne pas se donner la peine de l'insérer
# utilisez str_insert_or_raise si vous voulez une exception à la place
return into_me
else:
raise err
##############################################################
def str_insert_or_raise(from_me, into_me, at):
"""
Insère la chaîne dans
Insère APRÈS , pas avant
L'entrée doit être un index entier de ou une sous-chaîne de
Si est la chaîne '15', cette sous-chaîne sera recherchée,
'15' ne sera pas interprété comme un index/sous-script.
Les entrées et doivent avoir des méthodes __str__ définies.
Si ce ne sont pas déjà des chaînes, , sont convertis en chaînes.
Si vous essayez d'insérer quelque chose, mais nous ne pouvons pas trouver la position où
vous avez dit de l'insérer, alors une exception est garantie de contenir au moins
les trois sous-chaînes suivantes :
str_insert_or_raise.__name__
'non trouvé'
''
"""
try:
if isinstance(at, int):
return str_insert_by_int(from_me, into_me, at)
# Ci-dessous, les appels à str() fonctionnent bien si et sont déjà des chaînes
# cela les transforme en chaînes s'ils ne le sont pas déjà
return str_insert_by_str(str(from_me), str(into_me), str(at))
except ValueError as err:
serr = str(err)
if 'chaîne vide' in serr:
return into_me # Nous autorisons l'insertion de la chaîne vide
elif ("" in serr) and 'non trouvé' in serr:
msg_start = "Dans " + str_insert_or_raise.__name__ + ": "
msg = [msg_start, "\nchaîne d'entrée ", "", " non trouvée dans ", "",
"\nentrée <", str(at) , "> non trouvée dans <", str(into_me), ">"]
msg = ''.join(msg)
raise ValueError(msg) from None
else:
raise err
#############################################################
def str_insert_by_str(from_me, into_me, at):
"""
Insère la chaîne dans
place 'from_me' APRÈS 'at', pas avant 'at'
Par exemple,
str_insert_or_raise(at = '2', from_me = '0', into_me = '123')
place le zéro après le 2, pas avant le 2
L'appel renvoie '1203' et non '1023'
Lance des exceptions si les arguments d'entrée ne sont pas des chaînes.
De plus, si est vide ou si n'est pas une sous-chaîne de alors
une exception est levée.
Pour moins d'exceptions, utilisez à la place.
"""
try:
s = into_me.replace(at, at + from_me, 1)
except TypeError as terr: # les entrées pour replace ne sont pas des chaînes
msg_list = ['Les entrées pour la fonction ', str_insert_by_str.__name__, '() doivent être des chaînes']
raise TypeError(''.join(msg_list)) from None
# À la fin de l'appel à replace(), le '1' indique que nous allons remplacer
# la première occurrence de , au lieu de chaque occurrence de
if (s == into_me): # la chaîne n'est pas trouvée et/ou est une chaîne vide
msg_start = "Dans " + str_insert_by_str.__name__ + ": "
if from_me == '':
msg = ''.join([msg_start, "a tenté d'insérer une chaîne vide"])
raise ValueError(msg) from None
raise ValueError(msg_start, "Chaîne d'entrée non trouvée dans .",
"\nImpossible de déterminer où vous voulez insérer la sous-chaîne.") from None
return s
##################################################
def str_insert_by_int(from_me, into_me, at):
"""
* Insère la chaîne dans à l'index entier
* lance des exceptions si les arguments d'entrée ne sont pas des chaînes.
* Lance également une exception si vous essayez d'insérer la chaîne vide
* Si est inférieur à zéro, est placé au
début de
* Si est supérieur à l'index le plus grand de ,
est placé après la fin de
Pour moins d'exceptions, utilisez à la place.
"""
at = into_me[:(at if at > 0 else 0)]
return str_insert_by_str(from_me, into_me, at)
Utilisation
Le code ci-dessous démontre comment appeler la fonction str_insert
précédemment donnée
def foo(*args):
return args
F = 'F. '
s = 'En utilisant la chaîne \'John \' pour spécifier où faire l'insertion'
result = str_insert(from_me = F, into_me ='John Kennedy', at ='John ')
print(foo('\n\n', s, '\n', result))
s = 'En utilisant un entier renvoyé par find(\'Ken\') pour spécifier où faire l'insertion'
index = 'John Kennedy'.find('Ken') # renvoie la position de la première lettre de 'Ken', pas la dernière lettre
result = str_insert(from_me = F, into_me ='John Kennedy', at = index)
print(foo('\n\n', s, '\n', result))
s = 'En utilisant un entier (5) pour spécifier où faire l'insertion.'
result = str_insert(from_me = F, into_me ='John Kennedy', at = 5)
print(foo('\n\n', s, '\n', result))
s = "Recherche d'une chaîne 'at' qui n'existe pas"
result = str_insert(from_me = F, into_me ='John Kennedy', at ='x')
print(foo('\n\n', s, '\n', result))
s = ''.join(["Recherche de la chaîne vide.",
"\nTrouvez-en une immédiatement au début de la chaîne"])
result = str_insert(from_me = F, into_me ='John Kennedy', at = '')
print(foo('\n\n', s, '\n', result))
s = "Insérer une chaîne vide à l'index 3. Aucun changement visible"
result = str_insert(from_me = '', into_me = 'John Kennedy', at = 3)
print(foo('\n\n', s, '\n', result))
for index in [-5, -1, 0, 1, 997, 999]:
s = "index " + str(index)
result = str_insert(from_me = F, into_me = 'John Kennedy', at = index)
print(foo('\n\n', s, '\n', result))
Avertissement sur l'Impossibilité de Modifier en Place
Aucune des fonctions ci-dessus ne modifiera une chaîne "sur place". Les fonctions renvoient chacune une copie modifiée de la chaîne, mais la chaîne d'origine reste intacte.
Par exemple,
s = ''.join(["Ci-dessous ce que nous obtenons quand nous oublions ",
"d'écraser la chaîne avec la valeur",
"renvoyée par str_insert_or_raise :"])
examp_str = 'John Kennedy'
str_insert('John ', F, examp_str)
print(foo('\n\n', s, '\n', examp_str))
# examp_str est toujours 'John Kennedy' sans le F