在字符串中匹配括号的最有效或最优雅的方法是什么,如:
"f @ g[h[[i[[j[2], k[[1, m[[1, n[2]]]]]]]]]] // z"为了识别和用单字符形式替换[[ Part ]]括号?
我想要:

所有其他内容都完好无损,例如前缀@和后缀//窗体完好无损。
数学语法对不熟悉的人的解释:
函数对参数使用单个方括号:func[1, 2, 3]
部件索引使用双方括号:list[[6]]或单字符Unicode双括号:list〚6〛完成。
我的目的是在ASCII文本字符串中标识匹配的[[ ]]表单,并将其替换为Unicode字符〚 〛。
发布于 2011-04-25 09:23:30
好吧,这是另一个答案,稍微短一点:
Clear[replaceDoubleBrackets];
replaceDoubleBrackets[str_String, openSym_String, closeSym_String] :=
Module[{n = 0},
Apply[StringJoin,
Characters[str] /. {"[" :> {"[", ++n},
"]" :> {"]", n--}} //. {left___, {"[", m_}, {"[", mp1_},
middle___, {"]", mp1_}, {"]", m_}, right___} /;
mp1 == m + 1 :> {left, openSym, middle,
closeSym, right} /. {br : "[" | "]", _Integer} :> br]]示例:
In[100]:= replaceDoubleBrackets["f[g[h[[i[[j[2], k[[1, m[[1, n[2]]]]]]]]]]]", "(", ")"]
Out[100]= "f[g[h(i(j[2], k(1, m(1, n[2]))))]]"编辑
如果要用所指示的符号替换双括号,也可以使用Mathematica内置设施:
Clear[replaceDoubleBracketsAlt];
replaceDoubleBracketsAlt[str_String] :=
StringJoin @@ Cases[ToBoxes@ToExpression[str, InputForm, HoldForm],
_String, Infinity]
In[117]:= replaceDoubleBracketsAlt["f[g[h[[i[[j[2], k[[1, m[[1, n[2]]]]]]]]]]]"]
Out[117]= f[g[h[[i[[j[2],k[[1,m[[1,n[2]]]]]]]]]]]结果不会在这里正确显示,但它是一个Unicode字符串,包含您请求的符号。
发布于 2011-04-25 14:18:04
当我编写第一个解决方案时,我没有注意到您只是想用字符串中的[[替换〚,而不是表达式。您可以始终使用HoldForm或Defer作为

但是我想您已经知道了,您希望表达式是一个字符串,就像输入(上面的ToString@不起作用)
由于到目前为止,所有的答案都集中在字符串操作上,所以我将采用一种数字方法,而不是与字符串搏斗,这对我来说更自然。[的字符代码为91,]为93。因此,请执行以下操作

给出括号作为0/1向量的位置。我已经否定了结尾括号,只是为了帮助思考过程,并供以后使用。
注意:我只检查了91和93的可分性,因为我当然不期望您输入以下任何字符,但是如果出于某种原因,您可以很容易地使用91或93相等的布尔列表来AND上面的结果。

由此,可以找到Part的第一个双括号对的位置

事实上,在mma中,表达式不以[开头,而且两个以上的[不能连续出现,因为在上面的计算中已经隐式假定了[[[...。
现在,结束对的实现更加困难,但理解起来却很简单。其想法如下:
closeBracket中的每个非零位置,例如i,转到openBracket中的相应位置,并在其左侧找到第一个非零位置(例如j)。doubleCloseBrackets[[i-1]]=closeBracket[[i]]+openBracket[[j]]+doubleOpenBrackets[[j]]。doubleCloseBrackets是doubleOpenBrackets的对应物,在Part的]]对的第一个位置上是非零的。


因此,现在我们有一组布尔位置,用于第一个开括号。我们只需将charCode中的对应元素替换为等效的〚,类似地,用第一个近括号的布尔位置,我们将charCode中的相应元素替换为等效的〛。

最后,通过删除被更改的元素旁边的元素,您可以使用[[]]替换已修改的字符串为〚 〛。

注2:
我的很多MATLAB习惯已经在上面的代码中慢慢出现了,而且在Mathematica中也不完全是惯用的。然而,我认为这种逻辑是正确的,而且是可行的。我将让您来优化它(我认为您可以取消Do[])并使它成为一个模块,因为我需要更长的时间才能完成它。
代码作为文本
Clear["Global`*"]
str = "f[g[h[[i[[j[2], k[[1, m[[1, n[2]]]]]]]]]]]";
charCode = ToCharacterCode@str;
openBracket = Boole@Divisible[charCode, First@ToCharacterCode["["]];
closeBracket = -Boole@
Divisible[charCode, First@ToCharacterCode["]"]];
doubleOpenBracket =
Append[Differences@Accumulate[openBracket], 0] openBracket;
posClose = Flatten@Drop[Position[closeBracket, Except@0, {1}], 1];
doubleCloseBracket = ConstantArray[0, Dimensions@doubleOpenBracket];
openBracketDupe = openBracket + doubleOpenBracket;
Do[
tmp = Last@
Flatten@Position[openBracketDupe[[1 ;; i]], Except@0, {1}];
doubleCloseBracket[[i - 1]] =
closeBracket[[i]] + openBracketDupe[[tmp]];
openBracketDupe[[tmp]] = 0;,
{i, posClose}];
changeOpen =
Cases[Range[First@Dimensions@charCode] doubleOpenBracket, Except@0];
changeClosed =
Cases[Range[First@Dimensions@charCode] doubleCloseBracket,
Except@0];
charCode[[changeOpen]] = ToCharacterCode["\[LeftDoubleBracket]"];
charCode[[changeClosed]] = ToCharacterCode["\[RightDoubleBracket]"];
FromCharacterCode@
Delete[Flatten@charCode,
List /@ (Riffle[changeOpen, changeClosed] + 1)]发布于 2011-04-25 22:41:46
这是我的尝试。由于特殊字符的存在,粘贴的ASCII代码非常不可读,所以我首先提供了它在MMA中的外观的图片。
基本上,它所做的是:方括号总是唯一可识别为单或双。问题就在括号内。开始括号总是有模式字符串的字符-不含括号+[或[.这是不可能有一个[后面[或反之亦然,没有其他字符之间(至少,不是在无错误的代码)。
因此,我们使用这个挂钩,并开始寻找特定的匹配括号,即那些没有任何其他括号之间。因为我们知道这种类型,或者“.”或者“[.]”,我们可以用双括号符号替换后一个,用未使用的字符代替前者(我使用笑脸)。这样做是为了使他们不再在模式匹配过程的下一次迭代中扮演角色。
我们重复,直到所有括号被处理,最后笑脸再次转换为单一括号。
你看,这种解释比代码所用的字符更多;-)。

Ascii:
s = "f @ g[hh[[i[[jj[2], k[[1, m[[1, n[2]]]]]]]]]] // z";
myRep[s_String] :=
StringReplace[s,
{
Longest[y : Except["[" | "]"] ..] ~~ "[" ~~
Longest[x : Except["[" | "]"] ..] ~~ "]" :>
y <> "\[HappySmiley]" <> x <> "\[SadSmiley]",
Longest[y : Except["[" | "]"] ..] ~~ "[" ~~ Whitespace ... ~~ "[" ~~
Longest[x : Except["[" | "]"] ..] ~~ "]" ~~ Whitespace ... ~~
"]" :> y <> "\[LeftDoubleBracket]" <> x <> "\[RightDoubleBracket]"
}
]
StringReplace[FixedPoint[myRep, s], {"\[HappySmiley]" -> "[","\[SadSmiley]" -> "]"}]哦,Whitespace部分是因为在数学中,两个括号不一定是相邻的。a[ [1] ]和a[[1]]一样合法。
https://stackoverflow.com/questions/5776158
复制相似问题