Ответ 1
>>> n = 2
>>> groups = text.split('_')
>>> '_'.join(groups[:n]), '_'.join(groups[n:])
('20_231', 'myString_234')
Похоже, что это наиболее читаемый способ, альтернативой является регулярное выражение)
Есть ли способ 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')
Похоже, что это наиболее читаемый способ, альтернативой является регулярное выражение)
Используя 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
Мне нравится это решение, потому что оно работает без какого-либо экстренного регулярного выражения и может быть легко адаптировано к другому "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 раза быстрее, чем регулярные выражения.
Я выставил мое тестирование script онлайн. Вы можете ознакомиться и прокомментировать.
Это зависит от вашего шаблона для этого разделения. Поскольку, если первые два элемента всегда являются числами, например, вы можете создать регулярное выражение и использовать модуль re
. Он также может разделить вашу строку.
>>>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']
У меня была более длинная строка, чтобы разделить любой 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!