Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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.

share|improve this question
1  
What should [f] to be turned into? Left untouched? –  Öskå Aug 19 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 at 17:06
    
If adding the actual problem is too broad or otherwise inappropriate, I'm happy to roll back. –  bobthechemist Aug 19 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 at 17:27
1  
@Öskå close, all strings though: List[List["a"],List["b","c","d"],List["e",List["[f]",List["g"]]]]. –  bobthechemist Aug 19 at 17:44

2 Answers 2

up vote 4 down vote accepted

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}}}}
share|improve this answer
    
you may use SyntaxQ to check if it's a valid expression –  hieron Aug 19 at 18:00
    
@hieron What are you proposing? –  Mr.Wizard Aug 19 at 18:01
    
If[SyntaxQ@#, ToExpression@#, $Failed] & –  hieron Aug 19 at 18:03
    
@hieron I'm trying to understand how that is applicable to the problem at hand; are you suggesting using that as part of StringReplace or something else? –  Mr.Wizard Aug 19 at 18:06
    
as an alternative for the undocumented function. –  hieron Aug 19 at 18:10

@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}}}}
share|improve this answer
    
Finally I see what you were getting at. +1 However this isn't apparently what the OP wants (see comments). –  Mr.Wizard Aug 19 at 18:48
    
I know, Pickett found the solution, although your answer was interesting too. –  hieron Aug 19 at 18:49

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.