有没有一种Python的方法可以在给定分隔符的第n次出现后拆分字符串?
假设有一个字符串:
'20_231_myString_234'
它应该被拆分成两部分(以'_'为分隔符,在第二次出现后):
['20_231', 'myString_234']
或者说实现这一点的唯一方法是计数、分割和连接吗?
>>> n = 2
>>> groups = text.split('_')
>>> '_'.join(groups[:n]), '_'.join(groups[n:])
('20_231', 'myString_234')
看起来这是最易读的方法,另一种方法是使用正则表达式。
str.split
添加可选参数,则已经存在该参数,即 maxsplit
https://docs.python.org/3/library/stdtypes.html#str.rsplit - jamylak使用re
获取一个形如^((?:[^_]*_){n-1}[^_]*)_(.*)
的正则表达式,其中n
是一个变量:
n=2
s='20_231_myString_234'
m=re.match(r'^((?:[^_]*_){%d}[^_]*)_(.*)' % (n-1), s)
if m: print m.groups()
import re
def nthofchar(s, c, n):
regex=r'^((?:[^%c]*%c){%d}[^%c]*)%c(.*)' % (c,c,n-1,c,c)
l = ()
m = re.match(regex, s)
if m: l = m.groups()
return l
s='20_231_myString_234'
print nthofchar(s, '_', 2)
或者不使用正则表达式,采用迭代查找的方法:
def nth_split(s, delim, n):
p, c = -1, 0
while c < n:
p = s.index(delim, p + 1)
c += 1
return s[:p], s[p + 1:]
s1, s2 = nth_split('20_231_myString_234', '_', 2)
print s1, ":", s2
('20_231_', 'myString_234')
。分隔符也包含在内。 - cherrun(.*)
前插入分隔符。 - jamylak{{}}
。 - jamylak我喜欢这个解决方案,因为它不需要使用任何实际的正则表达式,并且可以轻松地适应另一个“nth”或分隔符。
import re
string = "20_231_myString_234"
occur = 2 # on which occourence you want to split
indices = [x.start() for x in re.finditer("_", string)]
part1 = string[0:indices[occur-1]]
part2 = string[indices[occur-1]+1:]
print (part1, ' ', part2)
我想提供我的意见。 split()
的第二个参数允许您在一定数量的字符串后限制分割:
def split_at(s, delim, n):
r = s.split(delim, n)[n]
return s[:-len(r)-len(delim)], r
在我的电脑上,@perreal提供的两种优秀答案(迭代查找和正则表达式)实际上比这种方法慢1.4倍和1.6倍(分别)。
值得注意的是,如果你不需要初始部分,它甚至可以更快。然后代码变成:
def remove_head_parts(s, delim, n):
return s.split(delim, n)[n]
我承认对于这个名称并不太确定,但它确实完成了工作。令人惊讶的是,它比迭代查找快2倍,比正则表达式快3倍。
我在我的测试脚本上线了。欢迎您进行评论和审查。
s = '20_231_myString_234'
first_part = text.rsplit('_', 2)[0] # Gives '20_231'
second_part = text.split('_', 2)[2] # Gives 'myString_234'
这不仅简单,而且避免了正则表达式解决方案和其他使用 join 撤消不必要拆分的性能损失。
>>>import re
>>>str= '20_231_myString_234'
>>> occerence = [m.start() for m in re.finditer('_',str)] # this will give you a list of '_' position
>>>occerence
[2, 6, 15]
>>>result = [str[:occerence[1]],str[occerence[1]+1:]] # [str[:6],str[7:]]
>>>result
['20_231', 'myString_234']
def split_nth(s, sep, n):
n_split_groups = []
groups = s.split(sep)
while len(groups):
n_split_groups.append(sep.join(groups[:n]))
groups = groups[n:]
return n_split_groups
s = "aaaaa bbbbb ccccc ddddd eeeeeee ffffffff"
print (split_nth(s, " ", 2))
['aaaaa bbbbb', 'ccccc ddddd', 'eeeeeee ffffffff']
我有一个更大的字符串需要每n个字符拆分一次,最终使用了以下代码:
# Split every 6 spaces
n = 6
sep = ' '
n_split_groups = []
groups = err_str.split(sep)
while len(groups):
n_split_groups.append(sep.join(groups[:n]))
groups = groups[n:]
print n_split_groups
感谢 @perreal!
这取决于您对此拆分的模式是什么。因为如果前两个元素总是数字,例如,您可以构建re
模块并使用正则表达式。它也能够拆分您的字符串。