2015-11-13 3 views
2

Как разбить этот многострочный разделитель, не создавая два списка и добавляя, которые, похоже, очень эффективны при выполнении операций.Разделительная строка с разделителем 1 и индексом [0] с другими

string = 'ABCD.EFGH.IJKLM|NOPQ|RSTUV' 

string.split("|")[0].split(".") + string.split("|")[1:] 
Out[156]: ['ABCD', 'EFGH', 'IJKLM', 'NOPQ', 'RSTUV'] 

Простой re.split(r'[.|]') не работает из-за во второй части строки.

string = 'ABCD.EFGH.IJKLM|NOPQ|RSTUV|D|F.g|.Y|' 

re.split(r'[./|]', string) 
Out[179]: ['ABCD', 'EFGH', 'IJKLM', 'NOPQ', 'RSTUV', 'D', 'F', 'g', '', 'Y', ''] 

данные NOPQ и RSTUV могут содержать ., но это не разделитель. Номер для столбцов, разделенных колонками, может увеличиваться. Но, всегда до первого |, разделитель . является seperater после первого | только | является разделителем.

Немногие другие возможные комбинации, которые могут быть данные,

string = 'ABCD.EFGH.IJKLM|NOPQ|RSTUV|DFGR' 
string.split("|")[0].split(".") + string.split("|")[1:] 
Out[174]: ['ABCD', 'EFGH', 'IJKLM', 'NOPQ', 'RSTUV', 'DFGR'] 

string = 'ABCD.EFGH.IJKLM|NOPQ|RSTUV|D.F.GR.' 
string.split("|")[0].split(".") + string.split("|")[1:] 
Out[176]: ['ABCD', 'EFGH', 'IJKLM', 'NOPQ', 'RSTUV', 'D.F.GR.'] 

string = 'ABCD.EFGH.IJKLM|NOPQ|RSTUV|D|F.g|.Y|' 
string.split("|")[0].split(".") + string.split("|")[1:] 
Out[178]: ['ABCD', 'EFGH', 'IJKLM', 'NOPQ', 'RSTUV', 'D', 'F.g', '.Y', ''] 

    string = 'ABCD.EFGH.IJKLM|NOPQ|RSTUV|D|F.g|Y|H|J|K|R|Y' 
string.split("|")[0].split(".") + string.split("|")[1:] 
Out[181]: ['ABCD', 'EFGH', 'IJKLM', 'NOPQ', 'RSTUV', 'D', 'F.g', 
'Y', 'H', 'J', 'K', 'R', 'Y'] 
+0

Try [это демо] (http://ideone.com/WT7mOx) - неважно, если реверсирование строки и использование обычного 're' модуля ускоряет работу, но является другой альтернативой модулю' regex'. –

+0

@stribizhev спасибо Я пробовал, что даже это идет медленно. Я фактически разбираю журнал с 20 М записей в день. И это всего лишь данные о игрушке, на самом деле есть от 35 до 62 колонок. – PKM15

+0

Я вижу.Очень жаль, что Python 're' не поддерживает' \ G'. –

ответ

3

новый ответ:

С модулем Re:

>>> import re 
>>> s = 'ABCD..EFGH.IJKLM|NOPQ|RSTUV|D|F.g|Y|H|J|K|R|Y||' 
>>> re.findall(r'(?<=\|)[^|]*|(?:(?<=\.)|\A)[^|.]*', s) 
['ABCD', '', 'EFGH', 'IJKLM', 'NOPQ', 'RSTUV', 'D', 'F.g', 'Y', 'H', 'J', 'K', 'R', 'Y', '', ''] 

Старый ответ:

С new regex module, вы можете сделать это:

>>> import regex 
>>> s = 'ABCD.EFGH.IJKLM|NOPQ|RSTUV|D|F.g|Y|H|J|K|R|Y' 
>>> regex.findall(r'\G\.?\K[^.|]+|[^|]+', s) 
['ABCD', 'EFGH', 'IJKLM', 'NOPQ', 'RSTUV', 'D', 'F.g', 'Y', 'H', 'J', 'K', 'R', 'Y'] 

demo

Где \G соответствует началу строки или следующей позиции после предыдущего совпадения, а \K отбрасывает все символы слева (необязательная точка здесь) из результата совпадения.

\G Используется для принудительного приближения всех результатов до первой трубы. Поскольку ничто не соответствует трубе в шаблоне, соприкосновение нарушается, а вторая ветвь [^|]+ используется для других предметов.

Примечание: таким же образом, вы можете выбрать, чтобы обеспечить примыкание во второй части строки с этим рисунком: \|\K[^|]+|[^|.]+(что может быть интересно, если вторая часть строки содержит много элементов). Но на этот раз нет необходимости использовать якорь \G, поскольку каждому смежному элементу предшествует труба.

Примечание2: если вы хотите, чтобы принять во внимание пустых элементов, вы можете изменить шаблон для:

regex.findall(r'\G(?:\A|\.)\K[^.|]*|[^|]+|(?<=\|)', s) 

или

regex.findall(r'\|\K[^|]*|(?:\.|\A)\K[^|.]*', s) 
0

Используйте re модуль. Использование re.split должно делать трюк, например. re.split('[|.]', string)

Смежные вопросы