Python在特定字符之前拆分

时间:2017-03-22 10:29:32

标签: python string split

我有以下字符串:

BUCKET1:/dir1/dir2/BUCKET1:/dir3/dir4/BUCKET2:/dir5/dir6

我试图以某种方式拆分它,我会回到下面的dict /其他数据结构:

BUCKET1 -> /dir1/dir2/, BUCKET1 -> /dir3/dir4/, BUCKET2 -> /dir5/dir6/

如果我只有一个BUCKET而不是多个,我可以以某种方式拆分它,如下:

res.split(res.split(':', 1)[0].replace('.', '').upper()) -> it's not perfect 

输入:ADRIAN:/ dir1 / dir11 / DANIEL:/ dir2 / ADI_BUCKET:/ dir3 / CULEA:/ dir4 / ADRIAN:/ dir5 / ADRIAN:/ dir6 /

输出:[(ADRIAN,/ dir1 / dir11),(DANIEL,/ dir2 /),(CULEA,/ dir3 /),(ADRIAN,/ dir5 /),(ADRIAN,/ dir6 /)

根据WiktorStribiżew的评论,以下正则表达式完成了这项工作:

 r"(BUCKET1|BUCKET2):(.*?)(?=(?:BUCKET1|BUCKET2)|$)"

4 个答案:

答案 0 :(得分:1)

使用re.findall()功能:

s = "ADRIAN:/dir1/dir11/DANIEL:/dir2/ADI_BUCKET:/dir3/CULEA:/dir4/ADRIAN:/dir5/ADRIAN:/dir6/"
result = re.findall(r'(\w+):([^:]+\/)', s)

print(result)

输出:

[('ADRIAN', '/dir1/dir11/'), ('DANIEL', '/dir2/'), ('ADI_BUCKET', '/dir3/'), ('CULEA', '/dir4/'), ('ADRIAN', '/dir5/'), ('ADRIAN', '/dir6/')]

答案 1 :(得分:1)

如果您有经验,我建议您像其他人一样建议学习正则表达式。但是,如果您正在寻找替代方案,那么在没有正则表达式的情况下,这样做是可行的。它还会产生您正在寻找的输出。

string = input("Enter:") #Put your own input here.

tempList = string.replace("BUCKET",':').split(":")
outputList = []
for i in range(1,len(tempList)-1,2):
    someTuple = ("BUCKET"+tempList[i],tempList[i+1])
    outputList.append(someTuple)

print(outputList) #Put your own output here.

这将产生:

[('BUCKET1', '/dir1/dir2/'), ('BUCKET1', '/dir3/dir4/'), ('BUCKET2', '/dir5/dir6')]

如果您对Regex不熟悉,可以更容易理解和操作此代码,但如果您熟悉如何使用它,我仍然会亲自推荐Regex解决此问题。

答案 2 :(得分:0)

使用正则表达式?

impore re
test = 'BUCKET1:/dir1/dir2/BUCKET1:/dir3/dir4/BUCKET2:/dir5/dir6'

output = re.findall(r'(?P<bucket>[A-Z0-9]+):(?P<path>[/a-z0-9]+)', test)
print(output)

哪个给出了

[('BUCKET1', '/dir1/dir2/'), ('BUCKET1', '/dir3/dir4/'), ('BUCKET2', '/dir5/dir6')]

答案 3 :(得分:0)

看来你有一个预定义的&#34;桶的列表&#34;您希望用作字符串内记录的边界。

这意味着,匹配这些键值对的最简单方法是匹配其中一个桶,然后是冒号,然后任何不启动等于那些桶名称的字符序列的字符

您可以使用

r"(BUCKET1|BUCKET2):(.*?)(?=(?:BUCKET1|BUCKET2)|$)"

如果您的值跨越多行,则使用re.S / re.DOTALL进行编译。请参阅regex demo

<强>详情:

  • (BUCKET1|BUCKET2) - 捕获匹配并存储在.group(1)任何存储桶名称中的组1
  • : - 冒号
  • (.*?) - 任意0个字符,尽可能少(因为*?是一个懒惰的量词),直到第一次出现(但不包含)......
  • (?=(?:BUCKET1|BUCKET2)|$) - 任何存储桶名称或字符串结尾。

在转义存储桶名称时动态构建它(只是为了安全起见,以防这些名称包含*+或其他特殊字符):

import re
buckets = ['BUCKET1','BUCKET2']
rx = r"({0}):(.*?)(?=(?:{0})|$)".format("|".join([re.escape(bucket) for bucket in buckets]))
print(rx)
s = "BUCKET1:/dir1/dir2/BUCKET1:/dir3/dir4/BUCKET2:/dir5/dir6"
print(re.findall(rx, s))
# => (BUCKET1|BUCKET2):(.*?)(?=(?:BUCKET1|BUCKET2)|$)
     [('BUCKET1', '/dir1/dir2/'), ('BUCKET1', '/dir3/dir4/'), ('BUCKET2', '/dir5/dir6')]

请参阅online Python demo