2010-09-07 13 views
34

Ho un sacco di stringhepitone: rimuovere sottostringa solo alla fine della stringa di

alcuni di loro hanno ' rec'

Voglio rimuovere che solo se questi sono gli ultimi 4 caratteri

giù di lì un altro parole

somestring='this is some string rec' 

voglio che sia:

somestring='this is some string' 

qual è il modo Python per avvicinarsi a questo?

+0

possibile duplicato del [Python Rimuovere gli ultimi 3 caratteri di una stringa] (http://stackoverflow.com/questions/1798465/python-remove-last-3-characters-of- a-string) – outis

+0

possibile duplicato di [Come rimuovere una sottostringa dalla fine di una stringa in Python?] (http://stackoverflow.com/questions/1038824/how-do-i-remove-a-substring- dalla fine alla fine di una stringa in python) –

risposta

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

somestring = rchop(somestring, ' rec') 
+3

roba buona; basta fare attenzione all'ombreggiamento del 'str' incorporato – bernie

+0

Notato e modificato. Grazie. –

+4

@Jack, 'string' è il nome di un modulo di libreria standard, che può anche avere una cattiva idea di nominare l'hashtall, non meno di un builtin ...! -) Piuttosto, ti consiglio di abituarti ad utilizzare gli identificatori come 'thestring',' astring', e simili, invece! -). –

4

Si potrebbe usare un'espressione regolare così:

from re import sub 

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

Qui catturare i gruppi è eccessivo. 'sub ('rec $', '', str)' funziona. –

19

Dal momento che si deve ottenere len(trailing) comunque (dove trailing è la stringa che si desidera rimuovere se si tratta di finale), mi consiglia di evitare la leggera duplicazione del lavoro che .endswith causerebbe in questo caso. Naturalmente, la prova del codice è nella tempistica, quindi, cerchiamo di fare un po 'di misura (nomi delle funzioni dopo gli intervistati proponendoli):

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 

dire che abbiamo chiamato questo file python a.py ed è in directory corrente; ora, ...:

$ 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 

Come si vede, le soluzioni RE-based sono "irrimediabilmente surclassati" (come spesso accade quando uno "overkills" Un problema - forse uno dei motivi ER hanno una cattiva rep nella comunità Python! -), anche se il suggerimento nel commento di @ Jack è molto meglio di quello originale di @ Andrew. Le soluzioni basate su stringhe, come previsto, shing, con il mio endswith -avvertendo uno con un vantaggio minuscolo su @ Jack (essendo solo il 15% più veloce). Quindi, entrambe le idee di pura stringa sono buone (oltre ad essere concise e chiare) - Preferisco la mia variante un po 'solo perché sono, per carattere, una persona frugale (qualcuno potrebbe dire, avara ;-) .. . "rifiuti non, non vuole", -)

+0

cosa hai uno spazio nell'importazione a '' a.xxx? – Blankman

+0

@Blankman, è un comando bash che esegue Python: il setup ('-s') è un argomento, il codice viene cronometrato l'altro. Ognuno è quotato, quindi non devo preoccuparmi di questo inclusi spazi e/o caratteri speciali, naturalmente. Separate sempre gli argomenti con gli spazi in bash (e la maggior parte delle altre shell, incluso il proprio cmd.exe di Windows, quindi sono abbastanza sorpreso dalla vostra domanda!), E citando argomenti in un comando shell per preservare spazi e caratteri speciali all'interno di ogni argomento non è nemmeno quello che definirei un uso particolare, raro o avanzato di qualsiasi shell ...! -) –

+0

Oh, vedo che hai ignorato 'endswith' come ho detto nella risposta di Jack. Caching the len evita anche la terribile chiamata di Python (e C's!). –

1

Come tipo di un generatore di linea si è unito:

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. 
""" 
8

Se la velocità non è importante, usiamo espressioni regolari:

import re 

somestring='this is some string rec' 

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

Utilizzando more_itertools, abbiamo può le stringhe rstrip che passano un predicato.

installazione

> pip install more_itertools 

Codice

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' 

Qui passiamo tutti gli elementi finali che desideriamo mettere a nudo dalla fine.

Vedere anche lo more_itertools docs per dettagli.

Problemi correlati