如何获取特定子字符串后的字符串?

2024-12-31 08:37:00
admin
原创
32
摘要:问题描述:如何获取特定子字符串后的字符串?"world"例如,我想获取my_string="hello python world, I'm a beginner" ...在本例中是", I'm a beginner":)解决方案 1:最简单的方法可能...

问题描述:

如何获取特定子字符串后的字符串?

"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
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   997  
  在项目管理领域,CDCP(Certified Data Center Professional)认证评审是一个至关重要的环节,它不仅验证了项目团队的专业能力,还直接关系到项目的成功与否。在这一评审过程中,沟通技巧的运用至关重要。有效的沟通不仅能够确保信息的准确传递,还能增强团队协作,提升评审效率。本文将深入探讨CDCP...
华为IPD流程   34  
  IPD(Integrated Product Development,集成产品开发)是一种以客户需求为核心、跨部门协同的产品开发模式,旨在通过高效的资源整合和流程优化,提升产品开发的成功率和市场竞争力。在IPD培训课程中,掌握关键成功因素是确保团队能够有效实施这一模式的核心。以下将从五个关键成功因素展开讨论,帮助企业和...
IPD项目流程图   40  
  华为IPD(Integrated Product Development,集成产品开发)流程是华为公司在其全球化进程中逐步构建和完善的一套高效产品开发管理体系。这一流程不仅帮助华为在技术创新和产品交付上实现了质的飞跃,还为其在全球市场中赢得了显著的竞争优势。IPD的核心在于通过跨部门协作、阶段性评审和市场需求驱动,确保...
华为IPD   39  
  华为作为全球领先的通信技术解决方案提供商,其成功的背后离不开一套成熟的管理体系——集成产品开发(IPD)。IPD不仅是一种产品开发流程,更是一种系统化的管理思想,它通过跨职能团队的协作、阶段评审机制和市场需求驱动的开发模式,帮助华为在全球市场中脱颖而出。从最初的国内市场到如今的全球化布局,华为的IPD体系在多个领域展现...
IPD管理流程   71  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用