在特定短语后切割字符串?
我有一堆字符串需要处理。这些字符串基本上是一个描述符后面跟着一些代码。我只想保留描述符。
'a descriptor dps 23 fd'
'another 23 fd'
'and another fd'
'and one without a code'
上面的代码是 dps
、23
和 fd
。它们的顺序可以随意,彼此之间没有关系,并且可能根本不存在(就像最后一个例子那样)。
这些代码的列表是固定的(或者至少可以预测),所以假设代码不会出现在合法的描述符中,我该如何去掉第一个代码之后的所有内容呢?
我在使用Python。
6 个回答
在编程中,有时候我们会遇到一些问题,特别是在使用某些工具或库的时候。这些问题可能会让我们感到困惑,尤其是当我们刚开始学习编程的时候。
比如,有人可能在使用某个特定的功能时,发现它没有按照预期工作。这时候,他们可能会去网上查找解决办法,比如在StackOverflow这样的论坛上提问。
在提问时,清楚地描述问题是非常重要的。这样其他人才能理解你的困扰,并给出有效的建议。通常,提问者会提供一些代码示例,说明他们的代码是如何运行的,以及遇到的问题是什么。
总之,编程中遇到问题是很正常的,关键是要学会如何有效地寻求帮助,并清晰地表达自己的问题。
codes = ('12', 'dps', '23')
def get_descriptor(text):
words = text.split()
for c in codes:
if c in words:
i = words.index(c)
return " ".join(words[:i])
raise ValueError("No code found in `%s'" % (text))
你似乎在描述的内容像这样:
def get_descriptor(text):
codes = ('12', 'dps', '23')
for c in codes:
try:
return text[:text.index(c)].rstrip()
except ValueError:
continue
raise ValueError("No descriptor found in `%s'" % (text))
比如说,
>>> get_descriptor('a descriptor dps 23 fd')
'a descriptor'
简单来说,正如@THC4K在评论中提到的:
string.split(pattern, 1)[0]
这里的string
是你最开始的字符串,pattern
是你想要“分割”的模式,1
表示最多只分割一次,而[0]
则表示取分割后返回的第一个元素。
实际操作:
>>> s = "a descriptor 23 fd"
>>> s.split("23", 1)[0]
'a descriptor '
>>> s.split("fdasfdsafdsa", 1)[0]
'a descriptor 23 fd'
这是一种更简洁的写法,虽然我之前写的内容也会保留在这里。
如果你需要去掉多个模式,这里可以使用reduce
这个内置函数:
>>> string = "a descriptor dps foo 23 bar fd quux"
>>> patterns = ["dps", "23", "fd"]
>>> reduce(lambda s, pat: s.split(pat, 1)[0], patterns, string)
'a descriptor '
>>> reduce(lambda s, pat: s.split(pat, 1)[0], patterns, "uiopuiopuiopuipouiop")
'uiopuiopuiopuipouiop'
这基本上是说:对于每一个pat
在patterns
中:拿string
来反复应用string.split(pat, 1)[0]
(就像上面解释的那样),每次都在上一次返回的结果上操作。你可以看到,如果字符串中没有任何模式,原始字符串还是会被返回。
最简单的答案是结合使用列表/字符串切片和string.find
:
>>> s = "a descriptor 23 fd"
>>> s[:s.find("fd")]
'a descriptor 23 '
>>> s[:s.find("23")]
'a descriptor '
>>> s[:s.find("gggfdf")] # <-- look out! last character got cut off
'a descriptor 23 f'
一个更好的方法(为了避免在模式缺失时切掉最后一个字符,当s.find
返回-1时)可能是把它放在一个简单的函数里:
>>> def cutoff(string, pattern):
... idx = string.find(pattern)
... return string[:idx if idx != -1 else len(string)]
...
>>> cutoff(s, "23")
'a descriptor '
>>> cutoff(s, "asdfdsafdsa")
'a descriptor 23 fd'
这里的[:s.find(x)]
语法意味着从字符串的第0个索引开始,取到冒号右边的部分;在这个例子中,右边的部分是s.find
的结果,它返回你传入字符串的索引。