7

The following string can be converted easily into a list with ToExpression

string = "{{a},{b,c,d},{e,{f,{g}}}}";
ToExpression@string

However, if the string contains characters that can be misinterpreted as syntax errors, I run in to problems.

string = "{{a},{b,c,d},{e,{[f],{g}}}}"

ToExpression throws an error since "[f]" isn't valid Wolfram.

(Side note, is that sentence grammatically correct? I would write "...isn't valid Java or C". Is it more appropriate to write "... isn't valid Wolfram Language?")

I would like to convert a string into a nested list of strings.

For reference (2242) starts with data whose Head is List and doesn't readily appear to work with nested lists, (43930) is a similar question focusing on Graph and looks promising except that the solution uses levelspec in Cases which, to my understanding, is not available in StringCases.

bobthechemist
  • 19,693
  • 4
  • 52
  • 138
  • 1
    What should [f] to be turned into? Left untouched? – Öskå Aug 19 '14 at 17:00
  • @Öskå left untouched. The actual string I am processing has a number of characters that Mathematica would misinterpret, but it looks as if braces {} are treated as they are in M. Everything other than braces should be left as strings. – bobthechemist Aug 19 '14 at 17:06
  • If adding the actual problem is too broad or otherwise inappropriate, I'm happy to roll back. – bobthechemist Aug 19 '14 at 17:19
  • For the first case you are expecting List[List[a],List[b,c,d],List[e,List["[f]",List[g]]]] as a result? – Öskå Aug 19 '14 at 17:27
  • Regarding the note I'm afraid "valid Wolfram Language" is the expectation, but I'm going to keep calling it Mathematica for the time being. – Mr.Wizard Aug 19 '14 at 17:43
  • 1
    @Öskå close, all strings though: List[List["a"],List["b","c","d"],List["e",List["[f]",List["g"]]]]. – bobthechemist Aug 19 '14 at 17:44

2 Answers2

5

Well I just saw your comment that says you want "all strings" so perhaps a different approach:

StringReplace["{{a},{b,c,d},{e,{[f],{g}}}}", 
  x : Except["{" | "," | "}"] .. :> "\"" <> x <> "\""] // ToExpression
{{"a"}, {"b", "c", "d"}, {"e", {"[f]", {"g"}}}}

If that doesn't work consider manipulating the raw box format produced by parseString:

parseString[s_String, prep : (True | False) : True] := 
  FrontEndExecute[FrontEnd`UndocumentedTestFEParserPacket[s, prep]]

fn[string_String] := 
 parseString[string][[1]] /.
  RowBox[x : {"[", __, "]"}] :> "\"" <> x <> "\"" // ToExpression

fn @ "{{a},{b,c,d},{e,{[f],{g}}}}"
{{a}, {b, c, d}, {e, {"[f]", {g}}}}
Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
2

@Mr.Wizard

s = StringReplace["{{a},{b,c,d},{e,{[f],{g}}}}", 
   x : Except["{" | "," | "}"] .. :> "\"" <> x <> "\""] // ToExpression
check = If[SyntaxQ@#, ToExpression@#, #] &;
ReplaceAll[s, x_String :> check@x] // InputForm

(*out*)
{{a}, {b, c, d}, {e, {"[f]", {g}}}}
hieron
  • 1,167
  • 6
  • 13