用\ t分割字符串的棘手方法

时间:2018-11-28 10:48:53

标签: python string python-3.x python-2.7 split

像这样的字符串:

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

如何“ pythonish / tricky”将上面的字符串拆分为列表?

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 :(得分:3)

也许使用正则表达式?

>>> 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:]]将丢失的标签重新放在后面。

答案 1 :(得分:2)

您可以通过触摸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']]

您不希望添加到字符串中,因为它会创建许多中间的“丢弃”字符串实例,这会减慢它的速度-使用列表更快,更省力。

答案 2 :(得分:0)

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']

答案 3 :(得分:0)

另一个带有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']