Вызов split в несколько раз, вероятно, будет неэффективным, поскольку он может создать ненужные промежуточные строки.Использование предложенного вами регулярного выражения не сработает, поскольку группа захвата получит только последний элемент, а не каждый из них.Расщепление с использованием регулярных выражений, как предложил obmarg, кажется наилучшим путем, если предположить, что вы ищете "уплощенный" список.
Если вы не хотите выровнять список, вы можете разбить его, используясначала регулярное выражение, а затем итерации по результатам, проверяя исходный ввод, чтобы увидеть, какой разделитель был использован:
items = re.split(r'\||<>', input)
offset = 0
for i in items:
delimiter = '|' if input[offset+len(i)] == '|' else '<>'
offset += len(i) + len(delimiter)
# Do something with i, depending on whether | or <> was the delimiter
Наконец, если вы вообще не хотите создавать подстроки (используя только начало инапример, конечные индексы для экономии места), re.finditer
может выполнить эту работу.Перебирайте разделители и делайте что-то с текстом между ними в зависимости от того, какой разделитель (|
или <>
) был найден.Это более сложная операция, поскольку вам придется обрабатывать множество угловых случаев, но, возможно, она того стоит в зависимости от ваших потребностей.
Обновление: для вашего конкретного случая, где формат вводаединообразно, решения обмарга - лучшие.Если необходимо, постобработайте результат, чтобы получить вложенный список:
split_result = re.split( "\||<>", input )
result = [split_result[0], split_result[1], [i for i in split_result[2:] if i]]
(последнее понимание списка должно обеспечить получение []
вместо ['']
, если послепоследний |
)
Обновление 2: Прочитав обновленный вопрос, я наконец понял, чего вы пытаетесь достичь.Вот полный пример с использованием ранее предложенного фреймворка:
items = re.split(r'\||<>', input) # Split input in items
offset = 0
result = [] # The result: strings for regular itens, lists for <> separated ones
acc = None
for i in items:
delimiter = '|' if offset+len(i) < len(input) and input[offset+len(i)] == '|' else '<>'
offset += len(i) + len(delimiter)
if delimiter == '<>': # Will always put the item in a list
if acc is None:
acc = [i] # Create one if doesn't exist
result.append(acc)
else:
acc.append(i)
else:
if acc is not None: # If there was a list, put the last item in it
acc.append(i)
else:
result.append(i) # Add the regular items
acc = None # Clear the list, since what will come next is a regular item or a new list
print result
Протестировано на вашем примере, результат был:
['a', 'b', 'c', 'de', ['f', 'ge', 'aha'],
'b', 'c', 'de', ['f', 'ge', 'aha'],
'b', 'c', 'de', ['f', 'ge', 'aha'],
'b', 'c', 'de', ['f', 'ge', 'aha'],
'b', 'c','de', ['f', 'ge', 'aha'],
'b', 'c', 'de', ['f', 'ge', 'aha'],
'b', 'c', 'de', ['f', 'ge', 'aha'],
'b', 'c', 'de', ['f', 'ge', 'aha'],
'b', 'c', 'de', ['f', 'ge', 'aha'],
'b', 'c', 'de', ['f', 'ge', 'aha'],
'b', 'c', 'de', ['f', 'ge', 'ah']]