我有以下字符串:
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)|$)"
答案 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')]