Хитрый способ разбить строку по \ t - PullRequest
0 голосов
/ 28 ноября 2018

Строка в таком виде:

x = dir\tsubdir1\t\tfile1.ext\t\tsubsubdir1\tsubdir2\t\tsubsubdir2\t\t\tfile2.ext

Как «разбить / хитро» разбить указанную выше строку на список?

dir
\tsubdir1
\t\tfile1.ext
\t\tsubsubdir1
\tsubdir2
\t\tsubsubdir2
\t\t\tfile2.ext

['dir', '\tsubdir1', '\t\tfile1.ext', '\t\tsubsubdir1', '\tsubdir2', '\t\tsubsubdir2', '\t\t\tfile2.ext']

Подтвердить концепцию:

x = r'dir\tsubdir1\t\tfile1.ext\t\tsubsubdir1\tsubdir2\t\tsubsubdir2\t\t\tfile2.ext'
y = x.split(r'\t')
print(y)

Ответы [ 4 ]

0 голосов
/ 28 ноября 2018

Другое решение регулярных выражений с findall ():

x = dir\tsubdir1\t\tfile1.ext\t\tsubsubdir1\tsubdir2\t\tsubsubdir2\t\t\tfile2.ext
re.findall(r"\t+[^\t]+|[^\t]+",x)                                                                                     
Out: 
['dir',
 '\tsubdir1',
 '\t\tfile1.ext',
 '\t\tsubsubdir1',
 '\tsubdir2',
 '\t\tsubsubdir2',
 '\t\t\tfile2.ext']
0 голосов
/ 28 ноября 2018

Вы можете сделать это, коснувшись каждого символа вашего path ввода один раз + некоторый список компов:

path = "dir\tsubdir1\t\tfile1.ext\t\tsubsubdir1\tsubdir2\t\tsubsubdir2\t\t\tfile2.ext"

l = [[]]
for c in path:
    if c != "\t":              # append to last element of list if not a \t
        l[-1].append(c)
    elif l[-1][-1] == "\t":    # also append to last element of list if it's last is a \t
        l[-1].append(c)        # (you could 'or' it into the if before)
    else:
        l.append([])           # else create a new "word" and append the \t
        l[-1].append(c)

l = [''.join(elem) for elem in l]   # join the things back together
print(l)

Вывод:

['dir', 
 '\tsubdir1', 
 '\t\tfile1.ext', 
 '\t\tsubsubdir1', 
 '\tsubdir2',
 '\t\tsubsubdir2', 
 '\t\t\tfile2.ext']

Перед объединением-шаг накопленные списки выглядят следующим образом:

[['d', 'i', 'r'], 
 ['\t', 's', 'u', 'b', 'd', 'i', 'r', '1'], 
 ['\t', '\t', 'f', 'i', 'l', 'e', '1', '.', 'e', 'x', 't'], 
 ['\t', '\t', 's', 'u', 'b', 's', 'u', 'b', 'd', 'i', 'r', '1'], 
 ['\t', 's', 'u', 'b', 'd', 'i', 'r', '2'], 
 ['\t', '\t', 's', 'u', 'b', 's', 'u', 'b', 'd', 'i', 'r', '2'], 
 ['\t', '\t', '\t', 'f', 'i', 'l', 'e', '2', '.', 'e', 'x', 't']]

Вы не хотите добавлять в строки, потому что это создает много промежуточных «выбрасываемых» экземпляров строк, что замедляет их - список использования гораздо быстрее и меньшештамм.

0 голосов
/ 28 ноября 2018
import re

x = 'dir\tsubdir1\t\tfile1.ext\t\tsubsubdir1\tsubdir2\t\tsubsubdir2\t\t\tfile2.ext'

s = re.sub('([^\t])\t', '\\1\n\t', x).split('\n')

print(s)

выход:

['dir', '\tsubdir1', '\t\tfile1.ext', '\t\tsubsubdir1', '\tsubdir2', '\t\tsubsubdir2', '\t\t\tfile2.ext']
0 голосов
/ 28 ноября 2018

Может быть, использовать регулярное выражение?

>>> import regex
>>> L = regex.split(r"(?<!\t)\t", "dir\tsubdir1\t\tfile1.ext\t\tsubsubdir1\tsubdir2\t\tsubsubdir2\t\t\tfile2.ext")
>>> L
['dir', 'subdir1', '\tfile1.ext', '\tsubsubdir1', 'subdir2', '\tsubsubdir2', '\t\tfile2.ext']
>>> L[:1] + ['\t' + i for i in L[1:]]
['dir', '\tsubdir1', '\t\tfile1.ext', '\t\tsubsubdir1', '\tsubdir2', '\t\tsubsubdir2', '\t\t\tfile2.ext']

Как это работает?

Регулярное выражение:

(?<!\t)\t

, что означает «табуляция, которой не предшествуетдругой вкладкой ", поэтому каждое первое табуляция в последовательности тегов соответствует регулярному выражению.Затем он используется в качестве метки разделения.

После разделения одна вкладка удаляется из каждого последующего элемента, поэтому последняя строка L[:1] + ['\t' + i for i in L[1:]] предшествует отсутствующей вкладке обратно.

...