String 使Mathematica中的字符串操作更方便
对于Mathematica,我总是觉得字符串是“二等公民”。与PERL之类的语言相比,要完成同样的任务,必须处理大量代码 可用的功能不错,但语法不太好。虽然有一些简写形式,例如String 使Mathematica中的字符串操作更方便,string,wolfram-mathematica,String,Wolfram Mathematica,对于Mathematica,我总是觉得字符串是“二等公民”。与PERL之类的语言相比,要完成同样的任务,必须处理大量代码 可用的功能不错,但语法不太好。虽然有一些简写形式,例如表示StringJoin和~表示StringExpression,但大多数字符串功能都缺少这种语法,并且使用了笨拙的名称,如:StringReplace,StringDrop,StringReverse,字符,字符范围,来自charactercode,以及常规表达式 在Mathematica中,字符串像数学对象一样处理,允
表示StringJoin
和~
表示StringExpression
,但大多数字符串功能都缺少这种语法,并且使用了笨拙的名称,如:StringReplace
,StringDrop
,StringReverse
,字符
,字符范围
,来自charactercode
,以及常规表达式
在Mathematica中,字符串像数学对象一样处理,允许5“a”+“b”
其中“a”
和“b”
充当符号。这是一个我不会改变的特性,即使这不会破坏代码堆栈。然而,它排除了某些简洁的字符串语法,例如表达式5“a”+“b”
将被呈现为“aaaaaab”
在Mathematica中,使字符串操作更方便的最佳方法是什么? 想到的想法,无论是单独的还是组合的,都是:
Take
,Replace
,Reverse
- 这是萨沙回答我问题的最初主题。这被认为是不可取的
StringReplace
>>StrRpl
,字符
>Chrs
,正则表达式
>>“RegEx”str[“string”]
,然后创建各种函数的定义。(这是列奥尼德·希夫林提出的。)“string”
>str[“s”、“t”、“r”、“i”、“n”、“g”]
,以便可以通过部分
、获取
等查看字符我认为这些操作之所以有String*名称,是因为它们与列表中的对应项相比差异很小。具体地说,与 现在实现您想要的方法是这样做:
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[];
您可以使用get
或Need
加载内容,并使用使用正确的上下文调用的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 "
不过,我不认为这样做是正确的做法。您可能会考虑在某些上下文中引入较短的符号,这些符号会自动评估到<代码>字符串*<代码>符号。我不确定超载是否是个好主意……我认为西蒙是对的。拥有字符串列表并将Map[…,Infinity]应用于这些函数将带来调试nightmare@Simon@belisarius离题了,有没有一个明显的原因让我投了反对票:?@Mr.fixed:)。这是X语言偏执者的一个常见行为,当他们看到一个来自酸奶瓶的答案时,我也认为重载不是一个好主意。您可能不仅会破坏代码(可以调试),还会破坏一些顶级内置(或第三方,如果您使用其他加载项)代码,甚至可能在不知情的情况下。如果我真的要重载列表函数,我会构造一个带有自定义头的类型(容器)(比如说
string
,这样字符串“abc”将被转换成string[“abc”]
),并且通过upvalue(比如string/:Take[s#u string,k#]:=Map[StringTake[#,k]&,s])重载该类型上感兴趣的列表函数(比如string/)。这样更安全。