OVH Cloud OVH Cloud

extraction de chaine

11 réponses
Avatar
Jean-Baptiste
une chaîne
s = "192.168.128.1"

je veux recupérer "192.168.128" chaine avant le dernier point et "1"
chaine apres le dernier point.
(sachant qu'il ne faut pas planter si il n'y a pas de points)

solution 1)

i = s.rfind(".")
if (i>= 0) :
s11 = s[i+1:]
s12 = s[:i]
else :
s11 = s
s12 = ""

solution 2)

s21 = s.split(".")[-1] #plutot joli
s22 = ".".join(s.split(".")[0:-1]) #assez mmoche

Qu'en pensez vous ?
performances ?
lisibilité ?

Rq: comme exemple on peut aussi prendre s = "c:\\rep1\\rep2\\fichier"
avec le separateur "\\"

10 réponses

1 2
Avatar
F. Petitjean
une chaîne
s = "192.168.128.1"

je veux recupérer "192.168.128" chaine avant le dernier point et "1"
chaine apres le dernier point.

solution 2)

s21 = s.split(".")[-1] #plutot joli
s22 = ".".join(s.split(".")[0:-1]) #assez mmoche

solution 3) (inspirée de solution 2)


def split_on_last(s, sep='.'):
"""retourne avant, après le dernier séparateur
"""
items = s.split(sep)
return sep.join(items[:-1]), items[-1]

split_on_last(s)
split_on_last(s, ',')
Je vous laisse copier/coller les résulats dans le __doc__ et écrire
l'appel à doctest qui va bien :-)

Rq: comme exemple on peut aussi prendre s = "c:rep1rep2fichier"
avec le separateur ""


Certainement pas ! Les fonctions de os.path ne sont pas faites pour les
chiens.
un exemple réel :
fname
'E:Program FilesBureau VeritasAriane-3Dynamic



6.2binCALCULATION.WDL'
os.path.split(fname)
('E:Program FilesBureau VeritasAriane-3Dynamic 6.2bin',



'CALCULATION.WDL')

et au moins os.path.split fonctionnera correctement sous AIX ou Solaris.



Avatar
kaerbuhez
une chaîne
s = "192.168.128.1"

je veux recupérer "192.168.128" chaine avant le dernier point et "1"
chaine apres le dernier point.
(sachant qu'il ne faut pas planter si il n'y a pas de points)




PythonWin 2.4.1 (#65, Mar 30 2005, 09:13:57) [MSC v.1310 32 bit (Intel)]
on win32.
Portions Copyright 1994-2004 Mark Hammond () -
see 'Help/About PythonWin' for further copyright information.

"192.168.128.1".rsplit('.', 1)
['192.168.128', '1']



"1921681281".rsplit('.', 1)
['1921681281']









J'ai loupé un truc ou string.rsplit est ce que tu cherches ?



Avatar
F. Petitjean
une chaîne
s = "192.168.128.1"

je veux recupérer "192.168.128" chaine avant le dernier point et "1"
chaine apres le dernier point.
(sachant qu'il ne faut pas planter si il n'y a pas de points)


"192.168.128.1".rsplit('.', 1)
['192.168.128', '1']



"1921681281".rsplit('.', 1)
['1921681281']









C'est parfait. On ne touche plus à rien !




Avatar
Jean-Baptiste
C'est exactement ce que je cherchais.
C'est quand même trop fort comme langage.
Mais c'est pas toujours facile de trouver ce qu'on veut dans l'aide.

Dans le même esprit comment supprimer des caractères:

"xx_blabla_12" -> "xxblabla12"

"xx_blabla_12".replace("_","") # le plus simple que j'ai trouvé
"".join("xx_blabla_12".split("_")) # un peu compliqué

y a pas un truc du genre "xx_blabla_12".remove("_")


Et enfin pour verifier qu'un chaine match un pattern:

par exemple vérifier que s correpond à [0-9]*
s = "123"
re.match(r"[0-9]*",s).group(0) == s
s = "1.23"
re.match(r"[0-9]*",s).group(0) == s

Y a surement plus simple non?




une chaîne
s = "192.168.128.1"

je veux recupérer "192.168.128" chaine avant le dernier point et "1"
chaine apres le dernier point.
(sachant qu'il ne faut pas planter si il n'y a pas de points)


"192.168.128.1".rsplit('.', 1)




['192.168.128', '1']

"1921681281".rsplit('.', 1)




['1921681281']



C'est parfait. On ne touche plus à rien !






Avatar
kaerbuhez
C'est exactement ce que je cherchais.
C'est quand même trop fort comme langage.
Mais c'est pas toujours facile de trouver ce qu'on veut dans l'aide.

Puis-je te suggérer ceci:

http://rgruet.free.fr/PQR24/PQR2.4.html#stringMethods

Plus tu l'utiliseras, plus tu iras vite.

Dans le même esprit comment supprimer des caractères:

"xx_blabla_12" -> "xxblabla12"

"xx_blabla_12".replace("_","") # le plus simple que j'ai trouvé


C'est comme ça que je fais aussi.

"".join("xx_blabla_12".split("_")) # un peu compliqué

y a pas un truc du genre "xx_blabla_12".remove("_")

;-)



Et enfin pour verifier qu'un chaine match un pattern:

par exemple vérifier que s correpond à [0-9]*
s = "123"
re.match(r"[0-9]*",s).group(0) == s
s = "1.23"
re.match(r"[0-9]*",s).group(0) == s

Y a surement plus simple non?

Comme je ne sais pas ce que tu veux dire par "correspond", difficile de

répondre mais si ton pattern est bien choisi, tu peux tester le matching
par l'existence d'un objet match:

import re
s = "123"
if re.match(r"[0-9]*",s): print 'Ca correspond ! .-)'
...



Ca correspond ! .-)





Note que dans ce cas-ci, ça ne teste rien du tout car * accepte zero
occurences de ce qui précede ...
Pour tester tes re, tu peux utiliser kiki:
http://project5.freezope.org/kiki

Voilà, amuse-toi bien !





une chaîne
s = "192.168.128.1"

je veux recupérer "192.168.128" chaine avant le dernier point et "1"
chaine apres le dernier point.
(sachant qu'il ne faut pas planter si il n'y a pas de points)


"192.168.128.1".rsplit('.', 1)





['192.168.128', '1']

"1921681281".rsplit('.', 1)





['1921681281']



C'est parfait. On ne touche plus à rien !



Tu bosses dans l'armée toi ?






Avatar
F. Petitjean


C'est parfait. On ne touche plus à rien !



Tu bosses dans l'armée toi ?


C'est tout de même bizarre la mémoire : l'armée, en deuxième classe
c'était en 1974 et l'autre jour je ne me rappelais plus le code de la
porte pour rentrer chez moi :-(

--
Je vous parle d'un temps que les moins de vingt ans ne peuvent pas
connaître. Charles Aznavour.



Avatar
Amaury Forgeot d'Arc
C'est exactement ce que je cherchais.
C'est quand même trop fort comme langage.
Mais c'est pas toujours facile de trouver ce qu'on veut dans l'aide.

Dans le même esprit comment supprimer des caractères:

"xx_blabla_12" -> "xxblabla12"

"xx_blabla_12".replace("_","") # le plus simple que j'ai trouvé
"".join("xx_blabla_12".split("_")) # un peu compliqué

y a pas un truc du genre "xx_blabla_12".remove("_")


c'est exactement ce que fait .replace("_","")
Ya pas plus court!

Et enfin pour verifier qu'un chaine match un pattern:

par exemple vérifier que s correpond à [0-9]*
s = "123"
re.match(r"[0-9]*",s).group(0) == s
s = "1.23"
re.match(r"[0-9]*",s).group(0) == s

Y a surement plus simple non?


Il suffit de mettre $ à la fin du motif:
re.match(r"[0-9]*$",s)

--
Amaury

Avatar
F. Petitjean
Dans le même esprit comment supprimer des caractères:

"xx_blabla_12" -> "xxblabla12"

"xx_blabla_12".replace("_","") # le plus simple que j'ai trouvé
"".join("xx_blabla_12".split("_")) # un peu compliqué

y a pas un truc du genre "xx_blabla_12".remove("_")


c'est exactement ce que fait .replace("_","")
Ya pas plus court!


Il y a plus court si vous avez plusieurs caractères différents à
supprimer :
si vous voulez supprimer à la fois les '_' et les 'a'
res = "xx_blabla_12".replace("_","").replace("a","")
C'est un peu lourd, déjà avec 2 caractères et c'est vite insupportable
avec plus.
La solution plus courte et plus rapide est basée sur string.translate:
from string import maketrans
tt = maketrans("", "")
"xx_blabla_12".translate(tt, "_a")
'xxblbl12'

string.translate est en général très efficace, mais inutilisable sur une
chaîne unicode.


Avatar
Guillaume Bouchard
F. Petitjean wrote:
si vous voulez supprimer à la fois les '_' et les 'a'
res = "xx_blabla_12".replace("_","").replace("a","")
C'est un peu lourd, déjà avec 2 caractères et c'est vite insupportable
avec plus.
La solution plus courte et plus rapide est basée sur string.translate:
from string import maketrans
tt = maketrans("", "")
"xx_blabla_12".translate(tt, "_a")
'xxblbl12'

string.translate est en général très efficace, mais inutilisable sur une
chaîne unicode.


j'aurais une solution qui marche avec les unicode et qui prend son
interet à partir de deux trois remplacements :

tt = string.maketrans(u'abcdef',u'_____')
str = 'chaine'.translate(tt).replace('_','')

Seul problème, cela ne marche pas, je ne sais pas pourquoi. La doc dit
que c'est le parametre deletion qui ne fonctionne pas avec unicode, hors
je ne l'utilise pas là. Doc pas à jour, fonction bugée ? À méditer.

Par contre, je trouve stupide l'implantation de cette fonction. pourquoi
ne pas faire une table de translation du type : (('_',''),('a','')) ce
qui serait bien plus propre et lisible et fonctionelle. Bref, à méditer.

--
Guillaume.

Avatar
Do Re Mi chel La Si Do
Bonsoir !


Et le code suivant ressemblerait plus à l'esprit souhaité ?

txt="xx_blabla_12"
mapc = {'a':'', '_':''} #liste des suppressions, ou des remplacements
print ''.join([mapc.get(i, i) for i in txt])


à noter que c'est compatible unicode :

txt=u"xx_blabla_12"
mapc = {u'a':u'', u'_':u''}
print ''.join([mapc.get(i, i) for i in txt]).encode('cp1252','replace')




Michel Claveau
1 2