2010-09-07 19 views
34

python: dizgeyi yalnızca dizenin sonunda kaldır

bir demet dizim var ' rec'

Bunu kaldırmak istiyorum sadece son 4 karakter

xzxx
somestring='this is some string rec' 
somestring='this is some string rec' 

Olmak için:

somestring='this is some string' 

Bu yaklaşıma python yolu nedir?

+0

olası yinelenen ([Python bir dizenin son 3 karakterleri kaldırın] http://stackoverflow.com/questions/1798465/python-remove-last-3-characters-of- a-string) – outis

+0

olası bir kopyası [Python'daki bir dizenin sonundaki bir alt dizeyi nasıl kaldırırım?] (http://stackoverflow.com/questions/1038824/how-do-i-remove-a-substring- -t-string-in-python) –

cevap

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

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

iyi şeyler; sadece dahili "str" ​​yi gölgelemek için dikkat edin. – bernie

+0

Noted ve düzenlenmiş. Teşekkür ederim. ! –

+4

@Jack, 'string' ... Bir yerleşiğine daha az olan nameclash için kötü bir fikir _also_ olabilecek bir standart kütüphanesi modülünün adıdır -) Aksine, ben kullanan tanımlayıcılar alışmak deneyin öneriyoruz "thestring", "astring" ve benzeri gibi! -). –

4

Siz de normal bir ifade kullanabilirsiniz: (trailing bunu sondaki oluyor EĞER kaldırmak istediğiniz dize olduğu)

from re import sub 

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

Yakalama grupları burada fazladır. alt ('rec $', '', str) 'çalışır. –

19

yine len(trailing) almak zorunda olduğundan, ben kaçınarak öneriyoruz Bu durumda .endswith'un neden olacağı hafif yineleme. Tabii ki, kodun kanıtı zamanlaması, yani, biraz ölçümü (katılımcılar onları öneren sonra işlevlerini adlandırma) yapalım:

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 

bu piton dosyası a.py adlandırdığınız Say ve İçinde geçerli dizin; Şimdi, ...:

$ 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 

, bir "overkills" bir sorun olduğunda sık olduğu gibi, RE tabanlı çözümler ("umutsuzca outclassed" olan Gördüğünüz gibi - nedenleri RE'lerin muhtemelen birine sahip böyle kötü Python topluluğundaki temsilcisi! -), Jack'in yorumundaki öneri, @ Andrew'in orijinalinden daha iyi. String tabanlı çözümler, beklediğim gibi, endswith ile, shing (@% 15 daha hızlı olmak üzere) üzerinde bir miniscule avantaja sahip olmaktan kaçınarak, shing. Yani, hem saf dize fikirleri iyi (hem özlü hem de açık olmanın yanı sıra) - Ben sadece benim varyantımı biraz tercih ederim, çünkü ben karakterim, tutumlu (bazıları dingin ;-) diyebilirim ki ..) .! "istemeseler değil, israf" -)

+0

İçe aktarımda bir alanınız var '' a.xxx? – Blankman

+0

@Blankman, bu Python çalıştıran bir bash komutudur: kurulum ('-s') bir argüman, kod diğerinin zamanlamasıdır. Her biri alıntı yapıldığı için boşluklar ve/veya özel karakter, os dersi de dahil olmak üzere endişelenmem gerekmiyor. Her zaman bağımsız değişkenleri boşluklarla (ve Windows 'kendi cmd.exe de dahil olmak üzere diğer kabuklarda, bu yüzden sorduğunuz soruya çok şaşırdım) ayırın ve her argümandaki boşlukları ve özel karakterleri korumak için bir kabuk komutuna argümanları alıntılayarak ! Ben herhangi bir kabuk ... bir tuhaf nadir veya gelişmiş kullanım dediğiniz kesinlikle da değil -) –

+0

keşke Jack'in cevapta belirtildiği gibi 'endswith' baypas görüyorum. Len'i önbelleğe almak ayrıca Python'un (ve C'nin!) Korkunç çağrı yükünü de önler. –

1

bir liner jeneratörün tür katıldı gibi: biz

import re 

somestring='this is some string rec' 

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

hız önemli değilse, normal ifadeler kullanabilirsiniz Bir yüklemi geçen rstrip dizeleri olabilir.

Kurulum

> pip install more_itertools 

Kod İşte

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' 

biz ucundan şerit isteyen tüm sondaki öğeleri geçmektedir.

Ayrıntılar için more_itertools docs'a da bakın.

0

more_itertools kullanma:

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

kullanım:

somestring.rsplit(' rec')[0] 
ait
İlgili konular