让我说事先知道字符串
"key1:key2[]:key3[]:key4"
应映射到"newKey1[]:newKey2[]:newKey3"
然后给出"key1:key2[2]:key3[3]:key4"
,
我的方法应该返回"newKey1[2]:newKey2[3]:newKey3"
(方括号内的数字顺序应该保留,如上例所示)
我的解决方案如下:
predefined_mapping = {"key1:key2[]:key3[]:key4": "newKey1[]:newKey2[]:newKey3"}
def transform(parent_key, parent_key_with_index):
indexes_in_parent_key = re.findall(r'\[(.*?)\]', parent_key_with_index)
target_list = predefined_mapping[parent_key].split(":")
t = []
i = 0
for elem in target_list:
try:
sub_result = re.subn(r'\[(.*?)\]', '[{}]'.format(indexes_in_parent_key[i]), elem)
if sub_result[1] > 0:
i += 1
new_elem = sub_result[0]
except IndexError as e:
new_elem = elem
t.append(new_elem)
print ":".join(t)
transform("key1:key2[]:key3[]:key4", "key1:key2[2]:key3[3]:key4")
打印newKey1[2]:newKey2[3]:newKey3
作为结果。
有人可以建议一个更好,更优雅的解决方案(尤其是正则表达式的使用)?
谢谢!
答案 0 :(得分:1)
只需在[]
上拆分映射结构,然后从实际数据中散布索引,最后将所有内容连接在一起,就可以更优雅地完成它:
import itertools
# split the map immediately on [] so that you don't have to split each time on transform
predefined_mapping = {"key1:key2[]:key3[]:key4": "newKey1[]:newKey2[]:newKey3".split("[]")}
def transform(key, source):
mapping = predefined_mapping.get(key, None)
if not mapping: # no mapping for this key found, return unaltered
return source
indexes = re.findall(r'\[.*?\]', source) # get individual indexes
return "".join(i for e in itertools.izip_longest(mapping, indexes) for i in e if i)
print(transform("key1:key2[]:key3[]:key4", "key1:key2[2]:key3[3]:key4"))
# newKey1[2]:newKey2[3]:newKey3
注意:在Python 3上使用itertools.zip_longest()
代替。
我仍然认为你过度设计了这个问题,并且对整个问题可能有一个更优雅,更不容易出错的方法。我建议退一步看看更大的图景,而不是仅仅因为它似乎解决了这个特殊的解决方案。