如何获取特定子字符串后的字符串?
- 2024-12-31 08:37:00
- admin 原创
- 32
问题描述:
如何获取特定子字符串后的字符串?
"world"
例如,我想获取
my_string="hello python world, I'm a beginner"
...在本例中是", I'm a beginner"
:)
解决方案 1:
最简单的方法可能就是拆分目标词
my_string="hello python world , i'm a beginner"
print(my_string.split("world",1)[1])
split 接受要拆分的单词(或字符)以及可选的拆分次数限制。
在这个例子中,在“世界”上进行分割并将其限制为只有一个分割。
解决方案 2:
我很惊讶没有人提及partition
。
def substring_after(s, delim):
return s.partition(delim)[2]
s1="hello python world, I'm a beginner"
substring_after(s1, "world")
# ", I'm a beginner"
恕我直言,这个解决方案比@arshajii 的解决方案更具可读性。除此之外,我认为@arshajii 的解决方案是最好的,因为它速度最快——它不会创建任何不必要的副本/子字符串。
解决方案 3:
s1 = "hello python world , i'm a beginner"
s2 = "world"
print(s1[s1.index(s2) + len(s2):])
如果要处理中不存在的s2
情况,s1
则使用s1.find(s2)
而不是index
。如果该调用的返回值为-1
,则s2
中不存在s1
。
解决方案 4:
您想要使用str.partition()
:
>>> my_string.partition("world")[2]
" , i'm a beginner "
因为这个选项比其他选项更快。
请注意,如果缺少分隔符,则会生成一个空字符串:
>>> my_string.partition("Monty")[2] # delimiter missing
''
如果想要保留原始字符串,则测试返回的第二个str.partition()
值是否非空:
prefix, success, result = my_string.partition(delimiter)
if not success: result = prefix
您还可以使用str.split()
限制为 1:
>>> my_string.split("world", 1)[-1]
" , i'm a beginner "
>>> my_string.split("Monty", 1)[-1] # delimiter missing
"hello python world , i'm a beginner "
但是,这种方法比较慢。在最佳情况下,与以下方法相比,str.partition()
这种方法至少要快 15%str.split()
左右:
missing first lower upper last
str.partition(...)[2]: [3.745 usec] [0.434 usec] [1.533 usec] <3.543 usec> [4.075 usec]
str.partition(...) and test: 3.793 usec 0.445 usec 1.597 usec 3.208 usec 4.170 usec
str.split(..., 1)[-1]: <3.817 usec> <0.518 usec> <1.632 usec> [3.191 usec] <4.173 usec>
% best vs worst: 1.9% 16.2% 6.1% 9.9% 2.3%
这显示了每次执行的时间,输入中的分隔符要么缺失(最坏情况),要么放在第一位(最佳情况),要么在下半部分、上半部分或最后位置。最快的时间标记为[...]
,<...>
最差的时间标记为。
上表是通过对所有三个选项进行综合计时测试得出的,如下所示。我在 2017 款 15 英寸 Macbook Pro(配备 2.9 GHz Intel Core i7 和 16 GB 内存)上运行了 Python 3.7.4 测试。
该脚本生成带有和不带有随机选择的分隔符的随机句子,如果存在,则在生成的句子的不同位置以随机顺序重复运行测试(产生最公平的结果,考虑到测试期间发生的随机操作系统事件),然后打印结果表:
import random
from itertools import product
from operator import itemgetter
from pathlib import Path
from timeit import Timer
setup = "from __main__ import sentence as s, delimiter as d"
tests = {
"str.partition(...)[2]": "r = s.partition(d)[2]",
"str.partition(...) and test": (
"prefix, success, result = s.partition(d)
"
"if not success: result = prefix"
),
"str.split(..., 1)[-1]": "r = s.split(d, 1)[-1]",
}
placement = "missing first lower upper last".split()
delimiter_count = 3
wordfile = Path("/usr/dict/words") # Linux
if not wordfile.exists():
# macos
wordfile = Path("/usr/share/dict/words")
words = [w.strip() for w in wordfile.open()]
def gen_sentence(delimiter, where="missing", l=1000):
"""Generate a random sentence of length l
The delimiter is incorporated according to the value of where:
"missing": no delimiter
"first": delimiter is the first word
"lower": delimiter is present in the first half
"upper": delimiter is present in the second half
"last": delimiter is the last word
"""
possible = [w for w in words if delimiter not in w]
sentence = random.choices(possible, k=l)
half = l // 2
if where == "first":
# best case, at the start
sentence[0] = delimiter
elif where == "lower":
# lower half
sentence[random.randrange(1, half)] = delimiter
elif where == "upper":
sentence[random.randrange(half, l)] = delimiter
elif where == "last":
sentence[-1] = delimiter
# else: worst case, no delimiter
return " ".join(sentence)
delimiters = random.choices(words, k=delimiter_count)
timings = {}
sentences = [
# where, delimiter, sentence
(w, d, gen_sentence(d, w)) for d, w in product(delimiters, placement)
]
test_mix = [
# label, test, where, delimiter sentence
(*t, *s) for t, s in product(tests.items(), sentences)
]
random.shuffle(test_mix)
for i, (label, test, where, delimiter, sentence) in enumerate(test_mix, 1):
print(f"
Running timed tests, {i:2d}/{len(test_mix)}", end="")
t = Timer(test, setup)
number, _ = t.autorange()
results = t.repeat(5, number)
# best time for this specific random sentence and placement
timings.setdefault(
label, {}
).setdefault(
where, []
).append(min(dt / number for dt in results))
print()
scales = [(1.0, 'sec'), (0.001, 'msec'), (1e-06, 'usec'), (1e-09, 'nsec')]
width = max(map(len, timings))
rows = []
bestrow = dict.fromkeys(placement, (float("inf"), None))
worstrow = dict.fromkeys(placement, (float("-inf"), None))
for row, label in enumerate(tests):
columns = []
worst = float("-inf")
for p in placement:
timing = min(timings[label][p])
if timing < bestrow[p][0]:
bestrow[p] = (timing, row)
if timing > worstrow[p][0]:
worstrow[p] = (timing, row)
worst = max(timing, worst)
columns.append(timing)
scale, unit = next((s, u) for s, u in scales if worst >= s)
rows.append(
[f"{label:>{width}}:", *(f" {c / scale:.3f} {unit} " for c in columns)]
)
colwidth = max(len(c) for r in rows for c in r[1:])
print(' ' * (width + 1), *(p.center(colwidth) for p in placement), sep=" ")
for r, row in enumerate(rows):
for c, p in enumerate(placement, 1):
if bestrow[p][1] == r:
row[c] = f"[{row[c][1:-1]}]"
elif worstrow[p][1] == r:
row[c] = f"<{row[c][1:-1]}>"
print(*row, sep=" ")
percentages = []
for p in placement:
best, worst = bestrow[p][0], worstrow[p][0]
ratio = ((worst - best) / worst)
percentages.append(f"{ratio:{colwidth - 1}.1%} ")
print("% best vs worst:".rjust(width + 1), *percentages, sep=" ")
解决方案 5:
如果你想使用正则表达式来做到这一点,你可以简单地使用一个非捕获组,来获取单词“world”,然后抓取之后的所有内容,就像这样
(?:world).*
示例字符串在此处进行测试
解决方案 6:
在 Python 3.9 中,removeprefix
添加了一个新方法:
>>> 'TestHook'.removeprefix('Test')
'Hook'
>>> 'BaseTestCase'.removeprefix('Test')
'BaseTestCase'
文档:https ://docs.python.org/3.9/library/stdtypes.html#str.removeprefix
公告:https ://docs.python.org/3.9/whatsnew/3.9.html
解决方案 7:
您可以使用名为 的包substring
。只需使用命令安装即可pip install substring
。只需提及起始和结束字符/索引即可获取子字符串。
例如:
import substring
s = substring.substringByChar("abcdefghijklmnop", startChar="d", endChar="n")
print(s)
输出:
# s = defghijklmn
解决方案 8:
尝试这个通用方法:
import re
my_string="hello python world , i'm a beginner"
p = re.compile("world(.*)")
print(p.findall(my_string))
# [" , i'm a beginner "]
解决方案 9:
这是一个老问题,但我遇到了非常相同的情况,我需要使用单词“low”作为分母来拆分字符串,对我来说问题是我在同一个字符串中有单词below和lower。
我使用 re 模块解决了这个问题
import re
string = '...below...as higher prices mean lower demand to be expected. Generally, a high reading is seen as negative (or bearish), while a low reading is seen as positive (or bullish) for the Korean Won.'
# use re.split with regex to match the exact word
stringafterword = re.split('\\blow\\b',string)[-1]
print(stringafterword)
# ' reading is seen as positive (or bullish) for the Korean Won.'
# the generic code is:
re.split('\\bTHE_WORD_YOU_WANT\\b',string)[-1]
希望这可以帮助到别人!
解决方案 10:
如果您倾向于仅使用 python 正则表达式库来执行此操作,Match.string
则可以使用对象的属性和Match.end()
方法来完成Match
:
import re
my_string="hello python world, I'm a beginner"
match = re.search("world", my_string)
if match:
print(match.string[match.end():])
# , I'm a beginner
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理必备:盘点2024年13款好用的项目管理软件