【发布时间】:2010-09-07 23:25:17
【问题描述】:
我有一堆字符串,其中一些有' rec'。仅当这些是最后 4 个字符时,我才想删除它。
也就是说我有
somestring = 'this is some string rec'
我希望它变成
somestring = 'this is some string'
解决这个问题的 Python 方法是什么?
【问题讨论】:
我有一堆字符串,其中一些有' rec'。仅当这些是最后 4 个字符时,我才想删除它。
也就是说我有
somestring = 'this is some string rec'
我希望它变成
somestring = 'this is some string'
解决这个问题的 Python 方法是什么?
【问题讨论】:
def rchop(s, suffix):
if suffix and s.endswith(suffix):
return s[:-len(suffix)]
return s
somestring = 'this is some string rec'
rchop(somestring, ' rec') # returns 'this is some string'
【讨论】:
endswith 也可以使用一组后缀来查找。如果有人使用此函数将元组作为suffix 传递,您将得到错误的结果。它将检查字符串列表,但删除字符串列表的长度,而不是匹配字符串的长度。
因为无论如何你都必须得到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
假设我们将这个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
如您所见,基于 RE 的解决方案“无可救药地被淘汰”(当一个人“过度解决”问题时经常发生这种情况——这可能是 RE 在 Python 社区中名声如此糟糕的原因之一!-),不过@Jack 评论中的建议比@Andrew 的原版要好得多。正如预期的那样,基于字符串的解决方案与我的endswith 相比,与@Jack 相比具有微不足道的优势(仅快15%)。所以,这两种纯字符串的想法都很好(以及简洁明了)——我更喜欢我的变体,只是因为从性格上来说,我是一个节俭的人(有人可能会说,小气;-)。 . “不浪费,不想要”!-)
【讨论】:
-s) 是一个参数,另一个是正在计时的代码。每个都被引用,所以我不必担心它包括空格和/或特殊字符,操作系统课程。你总是在 bash 中用空格分隔参数(以及大多数其他 shell,包括 Windows 自己的 cmd.exe,所以我对你的问题感到非常惊讶!),并在 shell 命令中引用参数以在每个参数中保留空格和特殊字符也绝对不是我所说的任何 shell 的特殊、罕见或高级用法......!-)
endswith,正如我在杰克的回答中提到的那样。缓存 len 还避免了 Python(和 C 的!)可怕的调用开销。
如果速度不重要,请使用正则表达式:
import re
somestring='this is some string rec'
somestring = re.sub(' rec$', '', somestring)
【讨论】:
从Python 3.9开始,可以使用removesuffix:
'this is some string rec'.removesuffix(' rec')
# 'this is some string'
【讨论】:
str.removeprefix)
这是杰克凯利及其兄弟答案的单行版本:
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
【讨论】:
你也可以使用正则表达式:
from re import sub
str = r"this is some string rec"
regex = r"(.*)\srec$"
print sub(regex, r"\1", str)
【讨论】:
sub(' rec$', '', str) 工作。
作为一种单线发电机加入:
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.
"""
【讨论】:
使用more_itertools,我们可以rstrip 传递谓词的字符串。
安装
> pip install more_itertools
代码
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'
在这里,我们传递了我们希望从末尾删除的所有尾随项。
有关详细信息,另请参阅more_itertools docs。
【讨论】:
从@David Foster's answer 汲取灵感,我愿意
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
【讨论】:
def remove_trailing_string(content, trailing):
"""
Strip trailing component `trailing` from `content` if it exists.
"""
if content.endswith(trailing) and content != trailing:
return content[:-len(trailing)]
return content
【讨论】:
使用:
somestring.rsplit(' rec')[0]
【讨论】: