web-dev-qa-db-fra.com

python: supprime la sous-chaîne uniquement à la fin de la chaîne

j'ai un tas de ficelles

certains d'entre eux ont ' rec'

je veux enlever cela seulement si ce sont les 4 derniers caractères

tellement d'autres mots

somestring='this is some string rec'

je veux que ce soit:

somestring='this is some string'

quelle est la façon python d'aborder cela?

def rchop(thestring, ending):
  if thestring.endswith(ending):
    return thestring[:-len(ending)]
  return thestring

somestring = rchop(somestring, ' rec')
66
Jack Kelly

Etant donné que vous devez obtenir len(trailing) de toute façon (où trailing est la chaîne que vous voulez supprimer SI elle est en fin de chaîne), je vous recommande d'éviter la légère duplication de travail que .endswith causerait dans ce cas. Bien sûr, la preuve du code est dans le timing, alors faisons quelques mesures (nommant les fonctions d'après les répondants les proposant):

import re

astring = 'this is some string rec'
trailing = ' rec'

def andrew(astring=astring, trailing=trailing):
    regex = r'(.*)%s$' % re.escape(trailing)
    return re.sub(regex, r'\1', astring)

def jack0(astring=astring, trailing=trailing):
    if astring.endswith(trailing):
        return astring[:-len(trailing)]
    return astring

def jack1(astring=astring, trailing=trailing):
    regex = r'%s$' % re.escape(trailing)
    return re.sub(regex, '', astring)

def alex(astring=astring, trailing=trailing):
    thelen = len(trailing)
    if astring[-thelen:] == trailing:
        return astring[:-thelen]
    return astring

Supposons que nous ayons nommé ce fichier python a.py et qu'il se trouve dans le répertoire en cours; à présent, ...:

$ python2.6 -mtimeit -s'import a' 'a.andrew()'
100000 loops, best of 3: 19 usec per loop
$ python2.6 -mtimeit -s'import a' 'a.jack0()'
1000000 loops, best of 3: 0.564 usec per loop
$ python2.6 -mtimeit -s'import a' 'a.jack1()'
100000 loops, best of 3: 9.83 usec per loop
$ python2.6 -mtimeit -s'import a' 'a.alex()'
1000000 loops, best of 3: 0.479 usec per loop

Comme vous le voyez, les solutions basées sur RE sont "désespérément surclassées" (comme cela arrive souvent quand on "surcharge" un problème - peut-être une des raisons pour lesquelles les RE ont une si mauvaise réputation dans la communauté Python! -), bien que la suggestion dans Le commentaire de @ Jack est bien meilleur que celui de @ Andrew. Les solutions basées sur des chaînes, comme prévu, ont été shing, avec ma endswith- en évitant celle qui présente un avantage minime par rapport à @ Jack (étant seulement 15% plus rapide). Donc, les deux idées pures sont bonnes (ainsi que concises et claires) - je préfère un peu ma variante parce que je suis, par caractère, un homme économe (certains diront peut-être, radin ;-) .. "ne gaspille pas, ne veux pas"! -)

21
Alex Martelli

Si la vitesse n'est pas importante, utilisez regex:

import re

somestring='this is some string rec'

somestring = re.sub(' rec$', '', somestring)
13

Vous pouvez également utiliser une expression régulière:

from re import sub

str = r"this is some string rec"
regex = r"(.*)\srec$"
print sub(regex, r"\1", str)
4
Andrew Hare

Voici une version à réponse unique de la réponse de Jack Kelly avec son frère ou sa sœur:

def rchop(s, sub):
    return s[:-len(sub)] if s.endswith(sub) else s

def lchop(s, sub):
    return s[len(sub):] if s.startswith(sub) else s
3
cdiggins

En tant que genre de générateur de ligne a rejoint:

test = """somestring='this is some string rec'
this is some string in the end Word rec
This has not the Word."""
match = 'rec'
print('\n'.join((line[:-len(match)] if line.endswith(match) else line)
      for line in test.splitlines()))
""" Output:
somestring='this is some string rec'
this is some string in the end Word 
This has not the Word.
"""
1
Tony Veijalainen

utilisation: 

somestring.rsplit(' rec')[0]
1
user6663257

S'inspirant de la réponse de @ David Foster }, je le ferais

def _remove_suffix(text, suffix):
    if text is not None and suffix is not None:
        return text[:-len(suffix)] if text.endswith(suffix) else text
    else:
        return text

Référence: Python string slicing

0
y2k-shubham

En utilisant more_itertools , nous pouvons rstrip chaînes qui transmettent un prédicat.

Installation

> pip install more_itertools

Code

import more_itertools as mit


iterable = "this is some string rec".split()
" ".join(mit.rstrip(iterable, pred=lambda x: x in {"rec", " "}))
# 'this is some string'

" ".join(mit.rstrip(iterable, pred=lambda x: x in {"rec", " "}))
# 'this is some string'

Nous passons ici tous les éléments suivants que nous souhaitons éliminer de la fin.

Voir aussi le more_itertools docs pour plus de détails.

0
pylang