第一次发生时拆分

2025-02-14 09:50:00
admin
原创
32
摘要:问题描述:在第一次出现分隔符时拆分字符串的最佳方法是什么?例如:"123mango abcd mango kiwi peach" 对第一个进行拆分,mango得到:" abcd mango kiwi peach" 若要在最后一次出现时进行拆分,请参阅Python 中的分...

问题描述:

在第一次出现分隔符时拆分字符串的最佳方法是什么?

例如:

"123mango abcd mango kiwi peach"

对第一个进行拆分,mango得到:

" abcd mango kiwi peach"

若要在最后一次出现时进行拆分,请参阅Python 中的分区字符串并获取冒号后最后一个段的值。


解决方案 1:

来自文档:

str.split([sep[, maxsplit]])

返回字符串中单词的列表,使用sep作为分隔符字符串。如果给出了maxsplit,则最多进行maxsplit次拆分(因此,列表最多包含maxsplit+1元素)。

s.split('mango', 1)[1]

解决方案 2:

>>> s = "123mango abcd mango kiwi peach"
>>> s.split("mango", 1)
['123', ' abcd mango kiwi peach']
>>> s.split("mango", 1)[1]
' abcd mango kiwi peach'

解决方案 3:

对我来说更好的方法是:

s.split('mango', 1)[-1]

...因为如果发生这种情况不在字符串中,那么您将得到“ IndexError: list index out of range"

因此-1不会受到任何伤害原因发生次数已经设置为一。

解决方案 4:

您还可以使用str.partition

>>> text = "123mango abcd mango kiwi peach"

>>> text.partition("mango")
('123', 'mango', ' abcd mango kiwi peach')

>>> text.partition("mango")[-1]
' abcd mango kiwi peach'

>>> text.partition("mango")[-1].lstrip()  # if whitespace strip-ing is needed
'abcd mango kiwi peach'

使用的优点str.partition是它总是会返回以下形式的元组:

(<pre>, <separator>, <post>)

因此这使得解包输出变得非常灵活,因为结果元组中总会有 3 个元素。

解决方案 5:

概括

最简单且性能最佳的方法是使用.partition字符串的方法

通常,人们可能想要获取找到的分隔符之前之后的部分,并且可能想要找到字符串中分隔符的第一次最后一次出现。对于大多数技术来说,所有这些可能性都大致一样简单,并且可以轻松地从一种转换为另一种。

对于以下示例,我们假设:

>>> import re
>>> s = '123mango abcd mango kiwi peach'

使用.split

>>> s.split('mango', 1)
['123', ' abcd mango kiwi peach']

第二个参数.split限制字符串被分割的次数。这将给出分隔符之前和之后的部分;然后我们可以选择我们想要的部分。

如果没有出现分隔符,则不进行拆分:

>>> s.split('grape', 1)
['123mango abcd mango kiwi peach']
Thus, to check whether the delimiter was present, check the length of the result before working with it.

使用.partition

>>> s.partition('mango')
('123', 'mango', ' abcd mango kiwi peach')

结果是一个元组,并且找到分隔符本身后就会保留。

当找不到分隔符时,结果将是一个相同长度的元组,结果中包含两个空字符串:

>>> s.partition('grape')
('123mango abcd mango kiwi peach', '', '')

因此,要检查分隔符是否存在,请检查第二个元素的值。

使用正则表达式

>>> # Using the top-level module functionality
>>> re.split(re.escape('mango'), s, 1)
['123', ' abcd mango kiwi peach']
>>> # Using an explicitly compiled pattern
>>> mango = re.compile(re.escape('mango'))
>>> mango.split(s, 1)
['123', ' abcd mango kiwi peach']

正则表达式的方法.split具有与内置字符串.split方法相同的参数,用于限制拆分次数。同样,当未出现分隔符时,不会进行拆分:

>>> grape = re.compile(re.escape('grape'))
>>> grape.split(s, 1)
['123mango abcd mango kiwi peach']

在这些示例中,re.escape没有效果,但在一般情况下,为了将分隔符指定为文字文本,这是必要的。另一方面,使用该re模块可以发挥正则表达式的全部功能:

>>> vowels = re.compile('[aeiou]')
>>> # Split on any vowel, without a limit on the number of splits:
>>> vowels.split(s)
['123m', 'ng', ' ', 'bcd m', 'ng', ' k', 'w', ' p', '', 'ch']

e(请注意和a之间的空字符串:that peach。)

使用索引和切片

使用.index字符串的方法找出分隔符的位置,然后使用该分隔符进行切片:

>>> s[:s.index('mango')] # for everything before the delimiter
'123'
>>> s[s.index('mango')+len('mango'):] # for everything after the delimiter
' abcd mango kiwi peach'

这直接给出了前缀。但是,如果找不到分隔符,则会引发异常:

>>> s[:s.index('grape')]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: substring not found

最后一次发生之后的所有内容

虽然没有被问到,但我还是在这里提供相关技术以供参考。

.split和技术.partition有直接对应项,用于获取字符串的最后一部分(即分隔符最后一次出现之后的所有内容)。供参考:

>>> '123mango abcd mango kiwi peach'.rsplit('mango', 1)
['123mango abcd ', ' kiwi peach']
>>> '123mango abcd mango kiwi peach'.rpartition('mango')
('123mango abcd ', 'mango', ' kiwi peach')

类似地,有一个.rindexto match ,但它仍然会给出分区的最后一个匹配项的开头的索引。因此.index

>>> s[:s.rindex('mango')] # everything before the last match
'123mango abcd '
>>> s[s.rindex('mango')+len('mango'):] # everything after the last match
' kiwi peach'

对于正则表达式方法,我们可以依靠反转输入的技术,寻找反转分隔符的首次出现,反转各个结果,并反转结果列表:

>>> ognam = re.compile(re.escape('mango'[::-1]))
>>> [x[::-1] for x in ognam.split('123mango abcd mango kiwi peach'[::-1], 1)][::-1]
['123mango abcd ', ' kiwi peach']

当然,这几乎肯定是得不偿失的。

另一种方法是使用从分隔符到字符串末尾的负向前瞻:

>>> literal_mango = re.escape('mango')
>>> last_mango = re.compile(f'{literal_mango}(?!.*{literal_mango})')
>>> last_mango.split('123mango abcd mango kiwi peach', 1)
['123mango abcd ', ' kiwi peach']

由于前瞻,这是一个最坏情况的 O(n^2) 算法。

性能测试

$ python -m timeit --setup="s='123mango abcd mango kiwi peach'" "s.partition('mango')[-1]"
2000000 loops, best of 5: 128 nsec per loop
$ python -m timeit --setup="s='123mango abcd mango kiwi peach'" "s.split('mango', 1)[-1]"
2000000 loops, best of 5: 157 nsec per loop
$ python -m timeit --setup="s='123mango abcd mango kiwi peach'" "s[s.index('mango')+len('mango'):]"
1000000 loops, best of 5: 250 nsec per loop
$ python -m timeit --setup="s='123mango abcd mango kiwi peach'; import re; mango=re.compile(re.escape('mango'))" "mango.split(s, 1)[-1]"
1000000 loops, best of 5: 258 nsec per loop

虽然更灵活,但正则表达式方法肯定更慢。限制拆分数量可以提高字符串方法和正则表达式的性能(未显示没有限制的时间,因为它们更慢并且给出不同的结果),但.partition仍然是明显的赢家。

对于此测试数据,该.index方法速度较慢,尽管它只需创建一个子字符串,并且不必迭代匹配之外的文本(为了创建其他子字符串)。预先计算分隔符的长度会有所帮助,但这仍然比 and 方法.split.partition

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

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

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

内置subversion和git源码管理

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

免费试用