0
$\begingroup$

enter image description here( Update: Note the "." in the expression, this is most likely what causes the problem. )**

Starting point of my question is the following code, which works as expected:

StringReplace[#,RegularExpression[" id=\".*\""] -> ""] &["nilo id=\"jaap\" de roock"]

Above, we see a pure function which removes substrings of type id="foo bar" from a string.

I want to store the pure function as a key/value pair in an association ( which will be persisted to some medium eventually ). I have done this before and usually works as expected.

I usually do this as follows:

data = <|parser -> "code"|>; 

where code represents the Mathematica code in question and if the code contains quotes (") then they are escaped as \".

A simple example of the procedure is the following:

"jaap" <> " en " <> "wim"
(* Out: "jaap en wim" *)

ass = <|"parser" -> "\"jaap\"<>\" en \"<> \"wim\""|>
(* Out: <|"parser" -> "jaap"<>" en "<> "wim"|> *)

ToExpression[ass["parser"]]
(* Out: "jaap en wim" *)

Now, when I apply this method to the code in question:

ass = <|"parser" -> ""|>

and attempt to insert the expression

StringReplace[#,RegularExpression[" id=\".*\""] -> ""] &["nilo id=\"jaap\" de roock"]

between the quotes where all quotes are escaped, Mathematica does not execute the command.

Like

"StringReplace[#,RegularExpression[\" id=\\".*\\ "\"]\[Rule]\"\"]&

No error is displayed but the dot is highlighted.

What have I done wrong? Is there an alternative?

$\endgroup$
11
  • $\begingroup$ I am not sure that I understand how to reproduce the behavior you see. Could you give explicit steps to reproduce, and perhaps a screenshot? $\endgroup$
    – MarcoB
    Feb 20, 2017 at 13:12
  • $\begingroup$ If you copy and paste the code lines in the original question then the last line will not work, or does it, in your case? $\endgroup$ Feb 20, 2017 at 13:28
  • 1
    $\begingroup$ for storage of code I would suggest to Compress and Uncompress instead of ToString and ToExpression. That is not only more efficient, it will also cure the problems you are seeing. I think I better don't ask what you are trying to do, you have been warned that parsing html with regular expressions might not turn out to not be such a good idea, haven't you :-) $\endgroup$ Feb 20, 2017 at 16:41
  • 1
    $\begingroup$ You need to escape the backslashes as well as the quotes, e.g. ToExpression["StringReplace[#,RegularExpression[\" id=\\\".*\\\"\"]\ \[Rule]\"\"]&"] $\endgroup$ Feb 20, 2017 at 19:44
  • 1
    $\begingroup$ @niloderoock: just made that answer. As for the html-parsing: I have done that myself, and in some cases I think it was OK. But it very soon gets more complicated as expected and will turn into a mess. The main problem is that you usually don't have control about the html content that you are parsing, so you never can be sure whether the subset that you cover will work for the next document your code is parsing... $\endgroup$ Feb 21, 2017 at 18:54

1 Answer 1

3
$\begingroup$

For storing arbitrary expressions to file and re-read them, using Compress and Uncompress will usually prevent from exactly the problems you have seen. Compress generates an ASCII string which will have no problems when transfered to a file and frees you from dealing with escaping characters and mostly also from encoding problems. Of course that will also work for other use cases where you need to serialize an arbitrary Mathematica expression. The only drawback I know is that you of course can not see what the content is when opening the files with an editor and you only can re-read it with Mathematica. For larger expression you get the extra benefit that the compressed data will be smaller and thus faster to write and read.

Here is the most simple version which would work to save:

filecontent = Compress[arbitraryExpression];
Export["file.txt",filecontent,"Text"];

and this is to read:

arbitraryExpression = Uncompress[Import["file.txt","Text"]]

if speed is relevant, as the compressed string is an ASCII string, you can even use BinaryWrite to save the filecontent and use FromCharacterCode@BinaryRead to read the string. Don't forget to Close the files when using that approach, otherwise you might collect some open file handles...

$\endgroup$

Your Answer

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

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