python:仅在字符串末尾删除子字符串

l--*_*''' 56 python string

我有一堆字符串

他们中的一些人 ' rec'

我想删除它只有那些是最后4个字符

再说一句话

somestring='this is some string rec'
Run Code Online (Sandbox Code Playgroud)

我希望它是:

somestring='this is some string'
Run Code Online (Sandbox Code Playgroud)

什么是python方法来解决这个问题?

Jac*_*lly 74

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

somestring = rchop(somestring, ' rec')
Run Code Online (Sandbox Code Playgroud)

  • @Jack,`string`是一个标准库模块的名称,可能_also_一个坏主意与nameclash一起,不低于内置......! - 而是,我建议你尝试习惯使用标识符这样的作为`thestring`,`astring`等,而不是! - ). (4认同)
  • 这就是为什么我们不做仓促的编辑,人们. (4认同)
  • @Matt Joiner:我不知道.我怀疑是一个方便的别名,因为对于大多数人来说,单词比阅读切片符号更容易. (2认同)
  • 在这种情况下,阴影是否真的重要?它只发生在函数调用范围内,对吗?因此,除非有人以需要使用原始`str`或`string`的方式扩展函数,否则它不会导致问题,在这种情况下似乎不太可能.可能形式不好..另见http://stackoverflow.com/a/2418007/210945 - PEP8推荐`string_`. (2认同)
  • 请注意, [`endswith`](https://docs.python.org/library/stdtypes.html#str.endswith) 也可以采用后缀元组来查找。如果有人使用此函数传递元组作为“后缀”,您将得到错误的结果。它将检查字符串列表,但删除字符串列表的长度,而不是匹配字符串的长度。 (2认同)

Ale*_*lli 22

因为你必须得到len(trailing)(如果trailing你想要删除的字符串在哪里),我建议避免.endswith在这种情况下导致的轻微重复工作.当然,代码的证明是在时间上,所以,让我们做一些测量(在受访者提出之后命名函数):

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
Run Code Online (Sandbox Code Playgroud)

假设我们已经命名了这个python文件a.py并且它位于当前目录中; 现在,...:

$ 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
Run Code Online (Sandbox Code Playgroud)

正如你所看到的那样,基于RE的解决方案"无可救药地超越"(通常在一个"过度杀伤"问题时发生 - 可能是RE在Python社区中有如此糟糕的代表的原因之一! - ),尽管建议在@ Jack的评论比@ Andrew的原创评论要好.正如预期的那样,基于字符串的解决方案与我的 - endswith避免- 解决方案相比@ Jack's具有微不足道的优势(仅快15%).所以,两个纯粹的想法都是好的(以及简洁和清晰) - 我更喜欢我的变体只是因为我,通过性格,节俭(有些人可能会说,吝啬;-)人.. . "浪费不可"!-)


Per*_*sen 17

如果速度不重要,请使用正则表达式:

import re

somestring='this is some string rec'

somestring = re.sub(' rec$', '', somestring)
Run Code Online (Sandbox Code Playgroud)


Xav*_*hot 15

从 开始Python 3.9,您可以使用removesuffix

'this is some string rec'.removesuffix(' rec')
# 'this is some string'
Run Code Online (Sandbox Code Playgroud)

  • 作为补充,这是由 [PEP616](https://www.python.org/dev/peps/pep-0616/) 引入的(带有 `str.removeprefix`) (4认同)

cdi*_*ins 7

这是杰克凯利的答案及其兄弟姐妹的单行版本:

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
Run Code Online (Sandbox Code Playgroud)