解释输入单元格框表达式的问题

WRe*_*ach 11 wolfram-mathematica

如何将从单元格表达式中提取的任意框规范转换为输入表达式?

这是我FullForm语法中Save Mathematica代码的回答.在该上下文中,模式匹配被用于从使用读取的笔记本表达式中提取框规范Import.

我认为ToExpression或者MakeExpression会做盒子解释的工作,但在某些情况下他们没有.

考虑一个包含表达式的输入单元格:

StringForm["a = ``", 1]
Run Code Online (Sandbox Code Playgroud)

这种细胞的细胞表达如下:

Cell[BoxData[
 RowBox[{"StringForm", "[", 
  RowBox[{"\"\<a = ``\>\"", ",", " ", "1"}], "]"}]], "Input"]
Run Code Online (Sandbox Code Playgroud)

我可以BoxData从这个单元格ToExpression中获取子表达式并使用获取相同的输出,就像我评估原始单元格一样:

ToExpression @
  BoxData[
    RowBox[{"StringForm", "[", 
      RowBox[{"\"\<a = ``\>\"", ",", " ", "1"}], "]"}]]
Run Code Online (Sandbox Code Playgroud)

但现在考虑以下输入表达式:

StringForm["a = ``", 1]

你必须仔细观察才能发现差异:a用斜体字表示.这是相应的单元格表达式:

Cell[BoxData[
 RowBox[{"StringForm", "[", 
  RowBox[{"\"\<\!\(\*
StyleBox[\"a\",
FontSlant->\"Italic\"]\) = ``\>\"", ",", " ", "1"}], "]"}]], "Input"]
Run Code Online (Sandbox Code Playgroud)

如果我正常评估这个单元格,我会得到预期的结果.但是,如果我尝试应用ToExpressionBoxData像以前一样的子表达式:

ToExpression @
  BoxData[
   RowBox[{"StringForm", "[", 
    RowBox[{"\"\<\!\(\*
  StyleBox[\"a\",
  FontSlant->\"Italic\"]\) = ``\>\"", ",", " ", "1"}], "]"}]]
Run Code Online (Sandbox Code Playgroud)

发生错误:

StringForm::string : String expected at position 1 in StringForm[]\) = '',
FontSlant->"\~\(\*\nStyleBox["a Italic, 1].
Run Code Online (Sandbox Code Playgroud)

对于许多(如果不是全部)内联字符串框转义序列,会发生同样的错误.我已经尝试明确指定表单ToExpressionMakeExpression,但我得到相同的错误.这让我想到了我的问题......

我需要做些什么才能模仿Mathematica从输入单元格表达式解释方框的方式?

Leo*_*rin 5

我认为这是一个错误.以下是我测试过的几个例子的解决方法:

Clear[toExpression];
toExpression[bd_BoxData] :=
   ToExpression[bd /.
      s_String :>
         StringReplace[
            StringReplace[s, "\n" :> ""],
            ShortestMatch[(start : "\(\*") ~~ body__ ~~ (end : "\)")] :> 
                   StringJoin[start, StringReplace[body, "\"" :> "\\\""], end]
         ]
   ];
Run Code Online (Sandbox Code Playgroud)

例如,我们从您的案例开始:

In[747]:= 
 BoxData["\"\<\!\(\*
    StyleBox[\"a\",
       FontSlant->\"Italic\"]\) = ``\>\""]//toExpression

Out[747]= a = ``
Run Code Online (Sandbox Code Playgroud)

如果我们现在检查单元格,它是:

BoxData["\<\"\\!\\(\\*StyleBox[\\\"a\\\",FontSlant->\\\"Italic\\\"]\\)\ = ``\"\>"]
Run Code Online (Sandbox Code Playgroud)

代替

BoxData["\"\<\!\(\*StyleBox[\"a\",FontSlant->\"Italic\"]\) = ``\>\""]
Run Code Online (Sandbox Code Playgroud)

(这是删除换行符的初始版本).而且,我认为,这应该是从一开始就应该有的.现在:

In[746]:= ToExpression@
   BoxData["\<\"\\!\\(\\*StyleBox[\\\"a\\\",FontSlant->\\\"Italic\\\"]\\) = ``\"\>"]

Out[746]= a = ``
Run Code Online (Sandbox Code Playgroud)

所以这已经很好了.

我不知道这项工作有多普遍,但它似乎适用于我尝试过的例子.主要的问题是,当一个像"字符串化"的东西aItalic,它应该是\\\"a\\\"\\\"Italic\\\"而不是\"a\"\"Italic\"-为逃逸本身逃逸人失踪.