Matching brackets in a string

后端 未结 9 1610
小蘑菇
小蘑菇 2020-12-03 03:47

What is the most efficient or elegant method for matching brackets in a string such as:

\"f @ g[h[[i[[j[2], k[[1, m[[1, n[2]]]]]]]]]] // z\"
<
9条回答
  •  南方客
    南方客 (楼主)
    2020-12-03 04:25

    Here is my attempt. The pasted ASCII code is pretty unreadable due to the presence of special characters so I first provide a picture of how it looks in MMA.

    Basically what it does is this: Opening brackets are always uniquely identifiable as single or double. The problem lies in the closing brackets. Opening brackets always have the pattern string-of-characters-containing-no-brackets + [ or [[. It is impossible to have either a [ following a [[ or vice versa without other characters in-between (at least, not in error-free code).

    So, we use this as a hook and start looking for certain pairs of matching brackets, namely the ones that don't have any other brackets in-between. Since we know the type, either "[... ]" or "[[...]]", we can replace the latter ones with the double-bracket symbols and the former one with unused characters (I use smileys). This is done so they won't play a role anymore in the next iteration of the pattern matching process.

    We repeat until all brackets are processed and finally the smileys are converted to single brackets again.

    You see, the explanation takes mores characters than the code does ;-).

    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]" -> "]"}]
    

    Oh, and the Whitespace part is because in Mathematica double brackets need not be next to each other. a[ [1] ] is just as legal as is a[[1]].

提交回复
热议问题