在Mathematica中使字符串操作更方便

时间:2011-04-16 22:08:57

标签: string wolfram-mathematica

对于Mathematica,我总觉得字符串是“二等公民”。与诸如PERL之类的语言相比,人们必须兼顾大量代码才能完成相同的任务。

可用的功能还不错,但语法不舒服。虽然有一些简写形式,例如<> StringJoin~~ StringExpression,但大多数字符串功能缺少此类语法,并使用笨拙的名称,如:{{ 1}},StringReplaceStringDropStringReverseCharactersCharacterRangeFromCharacterCode

在Mathematica中,字符串的处理方式与数学对象类似,允许RegularExpression 5 "a" + "b""a"作为符号。这是一个我不会改变的功能,即使这不会破坏代码堆栈。然而,它排除了某些简洁的字符串语法,例如,表达式"b"将被呈现为5 "a" + "b"


在Mathematica中使字符串操作更方便的最佳方法是什么?

单独或组合出现的想法是:

  1. 重载现有函数以处理字符串,例如"aaaaab"TakeReplace

    • 这是Sasha回答的问题的原始主题。它被认为是不可取的。

  2. 对字符串函数使用缩写名称,例如Reverse&gt;&gt; StringReplaceStrRpl&gt;&gt; CharactersChrs&gt;&gt; “正则表达式”

  3. 为字符串函数和可能的新字符串操作创建新的中缀语法。

  4. 为字符串创建一个新容器,例如RegularExpression,然后是各种功能的定义。 (这是由Leonid Shifrin提出的。)

  5. (4)的变量,将字符串(自动?)扩展为字符,例如str["string"]&gt;&gt; "string"以便str["s","t","r","i","n","g"]Part等可以看到角色。

  6. 从Mathematica中调用PERL等其他语言来处理字符串处理。

  7. 创建新的字符串函数,集合常用的操作序列。

1 个答案:

答案 0 :(得分:5)

我认为这些操作具有String *名称的原因是它们与列表对应物相比有微小的差异。明确地将CasesStringCases进行比较。

现在实现你想要的方法是这样做:

Begin["StringOverload`"];
{Drop, Cases, Take, Reverse};
Unprotect[String];
ToStringHead[Drop] = StringDrop;
ToStringHead[Take] = StringTake;
ToStringHead[Cases] = StringCases;
ToStringHead[Reverse] = StringReverse;
String /: 
 HoldPattern[(h : Drop | Cases | Take | Reverse)[s_String, rest__]] :=
  With[{head = ToStringHead[h]}, head[s, rest]]
RemoveOverloading[] := 
 UpValues[String] = 
  DeleteCases[UpValues[String], 
   x_ /; ! FreeQ[Unevaluated[x], (Drop | Cases | Take | Reverse)]]
End[];

您可以使用GetNeed加载内容,并使用正确的上下文删除调用RemoveOverloading[]的重载。

In[21]:= Cases["this is a sentence", RegularExpression["\\s\\w\\w\\s"]]

Out[21]= {" is "}

In[22]:= Take["This is dangerous", -9]

Out[22]= "dangerous"

In[23]:= Drop["This is dangerous", -9]

Out[23]= "This is "
但是,我不认为这样做是正确的方法。您可以考虑在某些上下文中引入较短的符号,这些符号会自动评估为String*符号