Here is one way:
splitAndGroup[list_List]:=Module[{splitedList}, splitedList=MapAt[StringSplit[#,"."]&,list,{All,1}]; Normal@GroupBy[splitedList,(#[[1,1]]&),MapAt[Last,{All,1}]] ] convert[list_List]:=Map[splitAndGroup,lst,{-3}] Now using:
lst = { "A" -> {"A1" -> {"a.124" -> "45", "a.125" -> "45"}, "A2" -> "something", "B" -> {"b[1].sqw" -> "true", "b[1].ewq" -> "false", "b[2].tyy" -> "saved", "b[2].bfg" -> "iid:"}, "C" -> "eb9d"} } You can do convert@lst to get:
{ "A"->{"A1"->{"a"->{124->45,125->45}}, "A2"->"something", "B"->{"b[1]"->{"sqw"->"true","ewq"->"false"}, "b[2]"->{"tyy"->"saved","bfg"->"iid:"}} ,"C"->"eb9d"} } And if you need it in Association form:
Needs["GeneralUtilities`"] ToAssociations@convert@lst <| "A"-><|"A1"-><|"a"-><|"124"->"45","125"->"45"|>|>, "A2"->"something", "B"-><|"b[1]"-><|"sqw"->"true","ewq"->"false"|>, "b[2]"-><|"tyy"->"saved","bfg"->"iid:"|>|>, "C"->"eb9d"|> |> Update
For the real case, there are lists that should not be splited. Like this one:
"dc" -> {"creator" -> "unknown", "format" -> "image/jpeg"} Just add a If in splitAndGroup, like this:
splitAndGroup[list_List]:=Module[{splitedList}, splitedList=MapAt[StringSplit[#,"."]&,list,{All,1}]; If[Length@splitedList[[1,1]]==1,Return@list]; Normal@GroupBy[splitedList,(#[[1,1]]&),MapAt[Last,{All,1}]] ]