1
$\begingroup$

The idea is to normalize a string before processing it to extract information from it. Strings may come with embedded outer brackets which are easily stripped or as elements of a true list. This is early in the development of parse but I just cannot figure out why it works fine with pure strings but fails when given in a list. It's not like I haven't worked much with Lists before. I'm now toward end of year 2 in experience with MMA. But other than labels and similar constructs I really have not done anything with strings considered intermediate or advanced.

Below is my nearly nude parse. In comments above it are things i tried but failed.

(* LabeledEcho 0.5.0 utilities: parse *)

ClearAll[LabeledEcho,parse];
ClearSystemCache[]

(* other things attempted on True *) 
(* condition to lift out the string *)
(* Take[str,{1,-1}] *)
(* First@str *)
(* Identity@@str *)
(* Replace[str,List->Identity] *)
(* Replace[str,List->Sequence] *)

parse[str : _String | List] := With[{
    expr = If[ListQ@str, Sequence @@ str, str]
    },
   cln = If[StringFreeQ[expr, {"{", ",", "}", Whitespace}], 
     Return[expr], StringDelete[expr, {"{", "}"}]];
   Echo[ cln, "cln \[Rule] "]
   ];

string = "{ABC,Its,easy,as,123},{as simple as Do re mi}, ABC, \
123,{Baby you and me girl,   }";
Head@string
str = parse[string]


list = {"{ABC,Its,easy,as,123},{as simple as Do re mi}, ABC, \
123,{Baby you and me girl,   }"};
Head@list
lst = parse[list]
$\endgroup$
6
  • 3
    $\begingroup$ Use parse[str : _String | _List] instead of parse[str : _String | List] (note the second underscore). $\endgroup$
    – Domen
    Commented Jun 10, 2022 at 10:54
  • 1
    $\begingroup$ You can do: lst = parse[First@list] but @Domen's answer is canonical and I will go with that.. $\endgroup$
    – Syed
    Commented Jun 10, 2022 at 10:57
  • $\begingroup$ @Syed Yeah I can easily do that but this is not about me. its about creating user-friendlyi tools for the end user. but that still leaves a mystery that doesn't explain why all the things i tried that should actually work but didn't. but thank you anyway. btw it worked but an end-user may not do that. and it is imnportant to me to create apps that are self-correcting when they can be. $\endgroup$ Commented Jun 10, 2022 at 11:16
  • 1
    $\begingroup$ @Domen nice flocking catch. im usually more careful with my pattens. thank you so much :) $\endgroup$ Commented Jun 10, 2022 at 11:21
  • 1
    $\begingroup$ parse[str : _String | {_String ..}] should do it. $\endgroup$
    – Syed
    Commented Jun 10, 2022 at 11:35

1 Answer 1

1
$\begingroup$

I recommend handling the String vs. List arguments with alternative definitions of your function. That would simplify your work, since each function definition would then "know what it has to deal with".

For instance, the following seems to reproduce the behavior of your parse function:

Clear[parse2]
parse2[str_String] := Echo[StringDelete[str, {"{", "}"}], "cln->"]
parse2[{str_String}] := parse2[str]

parse2[string]
parse2[list]

A couple of notes:

  • There is no need to check whether you have the characters you want to delete before deleting them. If they are not present, then StringDelete will simply return its argument unchanged. I noted that you were also checking for the presence of white space but then did not replace it out, so consider that as well.
  • In the handling of lists, your example has a list containing a single element. If you need to handle lists of strings with more than one element, then you could change the second definition to something like parse2[lst_?(VectorQ[#, StringQ]&)] := ... and then perhaps map the desired action over lst. However, it is not clear to me what your desired output should be if you have lists of more than one string.
$\endgroup$
2
  • $\begingroup$ thank you for the wonderful tips and input. i almost always handle types with their own definitions i thought i could cut a few corners this time. i always get burned when i do lol, i was reading the docs about how string manipulation functions work just as i heard the little bell alert me of your post. thanks again. :) $\endgroup$ Commented Jun 10, 2022 at 11:57
  • $\begingroup$ i decided to go with your suggestion which i have plenty of experience in, the beauty behind is that you actually write less code when doing this. for example if i have list of strings i dont have to repeat my strings parse definitions in the list definitions. i just call the parser again but with the individual string elements instead of the list. sort of like recursion. the strings definition will pick it up. we can do this with nearly all other types (within reason). it even handles error messages like a pro. $\endgroup$ Commented Jun 10, 2022 at 15:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.