[Question]
  [
Your challenge is to expand some brackets in a program's input as shown:
1. Find a string *s* between two matching brackets `[` and `]`, with a single digit *n* after the closing bracket.
2. Remove the brackets.
3. Replace *s* with itself repeated *n* times. (If *n* is 0, simply remove *s*.)
4. Go to step 1 until there are no more matching brackets in the input.
Additional rules and clarifications:
* You will take input and give output via any allowed means.
* A trailing newline in the output is allowed.
* You only need to handle printable ASCII in the input.
* You may assume that all brackets match, i.e. you will never receive the input `[]]]]` or `[[[[]`.
* You may assume that each closing bracket `]` has a digit after it.
Test cases:
```
Input                -> Output
[Foo[Bar]3]2         -> FooBarBarBarFooBarBarBar
[one]1[two]2[three]3 -> onetwotwothreethreethree
[three[two[one]1]2]3 -> threetwoonetwoonethreetwoonetwoonethreetwoonetwoone
[!@#[$%^[&*(]2]2]2   -> !@#$%^&*(&*($%^&*(&*(!@#$%^&*(&*($%^&*(&*(
[[foo bar baz]1]1    -> foo bar baz
[only once]12        -> only once2
[only twice]23456789 -> only twiceonly twice3456789
[remove me!]0        -> 
before [in ]2after   -> before in in after
```
As this is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), the shortest answer in each language wins. Good luck!
  
[Answer]
# [Gema](http://gema.sourceforge.net/), 17 characters
```
[#]?=@repeat{?;#}
```
Sample run:
```
bash-4.4$ gema '[#]?=@repeat{?;#}' <<< '[three[two[one]1]2]3'
threetwoonetwoonethreetwoonetwoonethreetwoonetwoone
```
[Answer]
# [Retina](https://github.com/m-ender/retina/wiki/The-Language), ~~24~~ ~~23~~ 22 bytes
```
+`\[([^][]*)](.)
$2*$1
```
[Try it online!](https://tio.run/##LYzNCsIwEITveYoUq7QVxG79vYkHX2LdYlq2WLBZCMGiL18T6mFh5pudcex7a8ppWj/umGFNSEVO2SZXKRRp4HgTwatxVBEoFMtUoh@FAP3TMVOlZhHhHBNEmFwWmC5rXBVZABDL2Inoxrhw3/BWxrnXR4ttQwv@zo99sFDt9ofj6azQ8SBv1gMntFUNd@JYY281gek8ux8 "Retina – Try It Online") This is practically a builtin in Retina 1. Edit: Saved 1 byte thanks to @Kobi. ~~47~~ 45 bytes in Retina 0.8.2:
```
].
]$&$*¶
{+`\[([^][]*)]¶
$1[$1]
\[([^][]*)]
```
[Try it online!](https://tio.run/##TYxNCsIwEIX3OUWKaakVxKb@7sSFHmKc0lSmWLAdCMGi3ssDeLGaUhcuBt773rxnydWt6cP4VPQ4F6gilXze4jUrzhBDjoDJFD1QKagUxR8UfQ9HZjgYixlqAdwSpuA6Rg3uaokwE6MY4BijHmCwn4AKc4iS2AM9lKFilqWx/p7@LR3mbg/J7cW39M@5rvZWZ8vVerPdCbDU8J1kQwEuREkVW5JQtxK1qRzZLw "Retina 0.8.2 – Try It Online")
[Answer]
# [Haskell](https://www.haskell.org/), ~~101~~ 96 bytes
```
fst.(""%)
infix 4%
s%']':d:r=(['1'..d]>>s,r)
s%'[':r|(t,q)<-""%r=s++t%q
s%x:r=s++[x]%r
s%e=(s,e)
```
[Try it online!](https://tio.run/##hZBvT4MwEMbf91N0OATcWKSb/4gsxhd@AV@eNcGtOCKsW1vddPrVxetAxgsTydFcf/c8l7suUv0iiqLKkocq02bkO44bkHyZ5Vs6cYl2Pe7F81glPniRNxrN@XSqhyqwFfBi9emb4Tq4DtGmEj0YGHeNpW28v8CWuwqvIvH1UARVmeZLmtDVq7k3ivZpRh24kxJuU8XHnDlkF5IuoL9fOKWIkdbRzQnIpeARmI3kDMxCCcHH1oAYmQ3LDgepRdZQWzmrDbVkI2ujPf8FBHo3R9B3H@H4xMc@bD8z9kKMFCFGm/wJCUAmJX1KFf4fOE3ULNyhdsfiHTea4bis8ygtZo3EbHLUsPHk7Pzi8qqV7PEha8oElCjlm6Cl6PHTTlsSflXfs6xIn3UVzlarHw "Haskell – Try It Online") Instead of using regular expression like most of the other answers, this implements a recursive parser.
*-5 bytes thanks to [BMO](https://codegolf.stackexchange.com/users/48198/bmo)!*
[Answer]
# [Perl 5](https://www.perl.org/), ~~34~~ ~~33~~ 29 + 1 (`-p`) = 30 bytes
```
s/.([^[]*?)](.)/$1x$2/e&&redo
```
[Try it online!](https://tio.run/##hZHdboMwDIXveQpXZRVFAkq67keTumkXu9sTWKlEO3dlKhiFdKx7@DFTKOVi0iInsr6cY9lJQWa/qMsI/GAZ@lH0/gBj@DiUFnZkCEqGimCT5LDh4gh2JyjJij1BmhcHW4oz9HCF2n@cai@cRm785aqIJhNDb1zX@MKMz4nRc63gvIIlCBbaxjB3kHPSMdqKtUK7M0R63hgEC2uiYZfDaUWNobVq1RpaScWtsTn/BQ6OnsboXq1w4ntSR516llqChQqU6JM/oYO4ZYZ1YmR/SzdxN/CANjPujzLRRtpVg0fpseoktkpFo@bXi5vbu/tecsKXrLt20FDGnwQZjfRsUNZZ05blLzHNQatka8n8cGFTzss6eF2Es3hWB8Uv "Perl 5 – Try It Online")
Cut it down with some help from @Shaggy and @TonHospel.
[Answer]
# [Japt v2](https://github.com/ETHproductions/japt), ~~21~~ ~~20~~ 19 bytes
*Saved 2 bytes thanks to @Shaggy*
```
e/.([^[]*?)](./@YpZ
```
[Test it online!](https://ethproductions.github.io/japt/?v=2.0a0&code=ZS8uKFteW10qPyldKC4vQFlwWg==&input=Ilt0aHJlZVt0d29bb25lXTFdMl0zIg==)
`e` is recursive replace, which makes one replacement at a time until there are no more matches. In this case, matches of the regex `/\[([^[]*?)](\d)/g` are replaced with with <inner text> repeated <digit> times until there are no more matches.
According to what I have planned ([here](https://github.com/ETHproductions/japt/issues/28)), this regex should eventually be at least ~~3~~ 2 bytes shorter:
```
‹[“⁽[»₋”]“.›
```
[Answer]
# JavaScript, ~~71~~ ~~67~~ 66 bytes
I *had* a 54 byte solution but it got screwed over by the second test case! :(
```
f=s=>s!=(x=s.replace(/.([^[]*?)](.)/,(_,y,z)=>y.repeat(z)))?f(x):x
```
---
## Test Cases
```
f=s=>s!=(x=s.replace(/.([^[]*?)](.)/,(_,y,z)=>y.repeat(z)))?f(x):x
o.innerText=`[Foo[Bar]3]2
[one]1[two]2[three]3
[three[two[one]1]2]3
[!@#[$%^[&*(]2]2]2
[[foo bar baz]1]1
[only once]12
[only twice]23456789
[remove me!]0
before [in ]2after`.split`\n`.map(x=>x.padEnd(22)+`:  `+f(x)).join`\n`
```
```
<pre id=o></pre>
```
[Answer]
# [Python 3](https://docs.python.org/3/), ~~110~~ ~~93~~ 92 bytes
```
import re
f=lambda s:f(re.sub(r'\[([^][]+)\](.)',lambda m:m[1]*int(m[2]),s))if'['in s else s
```
[Try it online!](https://tio.run/##hZLtSsMwFIb/7yoypjaZU7bUz4Ei/vAmzjJo3QkrLE1Jo2XefD392NINwXIa0vOc923z0mLvtzaP6zozhXWeORzpl11i0k3CyqXmDm/Lr5S7aAUc1grUtVgpvtqIaNZPmaWBhZpmuecGpBKzUohMRxBlOSsZ7kpkZV24hmsewYe18J44FSsZCTFhh@vmlREi0tVwPwpqm6NagK@skuC3DlHFrQupCVG/qaYfloG6fW7UnY@SQd3NV7ZzadZ/GwPj8dsELi7XcDXlZCqPRyNjQkQIUB03fzYHfqCtZWni6P6h71wckiK/ATnJZbenBD7pVCextrn0SJ7P@yojgYzv7h8en55DjgcUdv3IwMChsd/IDI7V/OyFYSpFbR0yoD9ByUR7dCGXnhGialn9Cw "Python 3 – Try It Online")
-17 bytes thanks to pizzapants184
-1 byte thanks to Kevin Cruijssen
[Answer]
# [Scala](http://www.scala-lang.org/), 173 bytes
```
l.foreach{x=>def r(c:String):String={val t="""\[([^\[\]]*)\](.)""".r.unanchored;c match{case t(g,h)=>r(c.replaceAllLiterally(s"[$g]$h",g*h.toInt));case _=>c}};println(r(x))}
```
[Try it online!](https://tio.run/##XZDbSgMxEIbvfYo0VklKWWzquWyxXghCvfIym0qazh4kTZZs7MGyz76mq2hrIAS@L/PPMJWSWjZ2/g7KoxdZGAQbD2ZRoUlZot3JSmqkUYymReXJCWoP5k/W8kfpxFAw3P@l1oAYcL@2gnGfOwAxPLAt2dvvf4Id2c7DKe@ezfh5jwTDjnJ5ai2aSxfuZygcHLXUW2SNCoHsP/brInA2vLy6vrm9O7AOlnYFaAkdcfGH55BaB4iHFQgmUw8Ot4o2OtobqfLdJh4vIEWOqPtX7wqT0Z833u0X5WOMccIJnyU8EaJHE0EiGljkog8jjcpDzmKk0FL6kKZkBciTrJ/TeBwyIwellgomWk@L0F9qvSUV5t1MdHPcz3p55O2z8ZSO2tK3eKzqelSGAbw2xJENpXVTN18 "Scala – Try It Online")
### Expanded:
```
l.foreach { x =>
  def remove(current: String): String = {
    val test ="""\[([^\[\]]*)\](.)""".r.unanchored
    current match {
      case test(g, h) => remove(current.replaceAllLiterally(s"[$g]$h", g * h.toInt))
      case _ => current
    }
  }
  println(remove(x))
}
```
# Old solution
# [Scala](http://www.scala-lang.org/), ~~219~~ ~~215~~ ~~213~~ ~~212~~ ~~199~~ bytes
```
l.foreach{x=>def r(c:String):String={"""\[([^\[\]]*)\](.)""".r.findFirstMatchIn(c).map{x=>val g=x.group(1);val h=x.group(2).toInt;r(c.replaceAllLiterally(s"[$g]$h",g*h))}.getOrElse(c)};println(r(x))}
```
[Try it online!](https://tio.run/##XZBda8IwFIbv/RUxcyMRCbPuWzrmYIKg7GKXaYRYTz9GTEqauTrxt3epG04XOASeJznv4ZSxVLI2i3eIHZrJXCOoHOhliUZFgbattVRIoRBN89KRFtofzMfG8GdpxUAEuHegRoPoc/dpRMBdZgHE4MjuSWN/3ongxLafznjnfM4vusSb4KQvT4xBC2l9ffmP/ZNItUFGx75h8B@7z9zzYHB1fXN7d39kLazMGtAK2uLyDy8gMRYQ9ysQgUwcWLxXtFasMTLOtlX4uIQEWRI/vDmb65T@3uEWYxxxwucRj4To0kgQRj1jliW5Xo5zW7qZdHE20SSmbCWLplmz3TSsWGrNR0H6dNiA7AACypyZaDf0gcxCoWQMI6WmuR9OKrUhJeadVHQy3Eu7GaU7loJ7tS@qBB@yGxZ@NKc0saTyst7V3w "Scala – Try It Online")
### Expanded:
```
l.foreach { x =>
  def remove(current: String): String = {
    """\[([^\[\]]*)\](.)""".r.findFirstMatchIn(current).map { x =>
      val g = x.group(1)
      val h = x.group(2).toInt
      remove(current.replaceAllLiterally(s"[$g]$h", g * h))
    }.getOrElse(current)
  }
  println(remove(x))
}
```
Where l is the list of strings that we will process.
Thanks Kevin Cruijssen for -1 byte
Went from 212 to 199 by removing an unused parameter, didn't pay attention.
[Answer]
# [Stacked](https://github.com/ConorOBrien-Foxx/stacked), ~~39~~ 38 bytes
*Saved 1 byte thanks to Shaggy, golfed the regex!*
```
['\[([^[\]]+)](.)'{.y x:x#~y*}recrepl]
```
[Try it online!](https://tio.run/##LYxRT8JAEITf71dsA3oFI5ErKPJgGh/8E8uSXNu92Nh2yXEK1ehfr9fAwyQ7387MMdjyg6thQL3DFPe4I7qbUbqY6Z9FD@ftefLXz389l54PDQ351imNbyL4aj1lZBRKx7TEcBIyGN49M2Xqcozw8iYzwiSf4PRmj7fzNAIzltGJQGF91HeMLce5pgfpytgyVxdOdbQmW60fnzbPCj238sXQckIPqmAnngHrDshYF9jHVURLpqCspFVFa9bQ1B0fAXVeV3D/ArnTiXwGgtYehn8 "Stacked – Try It Online")
Simply recursively replaces a regex `'\[([^[\]]+)](.)'` with the repetition rule.
[Answer]
# Python 3, ~~155~~ ~~148~~ ~~101~~ 97 bytes
```
def f(x):
 a=x.rfind('[')
 if~a:b=x.find(']',a);x=f(x[:a]+x[a+1:b]*int(x[b+1])+x[b+2:])
 return x
```
[Try It Online](https://tio.run/##bY3dSgMxEEbv9ynSqt1NV6Wb9TdSEC98iWGEpJ3QgE1KiDb1wldfsy0ouzgwDHznzMzuEDfetVer4@y6NRlmqsRlwdQyXQdj3boqoeQFs@ZbSZ3DU4blpeJPaZltkArrBKpupMa5dTFHum6Q1/0UEvN2oPgRHEvdLvSCqabw6j28qIAtiinnxR/wjrCBuPcoIG4CEbZD4Rj2wklFMRYmz2dwfvEGs3mVoRg/AOM90yrk/srrzfj9@4F5t8qXxT8k7m1Gor25vbt/eBwKgbb@k9iWJrgYEE3GB2JgHUOhTKSQMfutovsB)
Thanks to HyperNeutrino and Mego for -47 bytes and user202729 for -4 bytes.
[Answer]
# [JavaScript](https://developer.mozilla.org/bm/docs/Web/JavaScript) - ~~77~~ ~~75~~ 72 bytes
```
f=a=>a.replace(/(.*)\[([^[]*?)](.)(.*)/,(a,b,c,d,e)=>f(b+c.repeat(d)+e))
```
Edit: updated regex with Shaggy's recommendation
**Snippet:**
```
const test = ["[Foo[Bar]3]2", "[one]1[two]2[three]3", "[three[two[one]1]2]3", "[!@#[$%^[&*(]2]2]2", "[[foo bar baz]1]1", "[only once]12", "[only twice]23456789", "[remove me!]0", "before [in ]2after"];
const f=a=>a.replace(/(.*)\[([^[]*?)](.)(.*)/,(a,b,c,d,e)=>f(b+c.repeat(d)+e))
d.innerHTML=test.map(f).join("<br>");
```
```
<p id="d">
```
[Answer]
# [QuadR](https://github.com/abrudz/QuadRS) with the `≡` argument, ~~30~~ 28 bytes
```
\[[^[]+?].
∊(⍎⊃⌽⍵M)⍴⊂1↓¯2↓⍵M
```
[Try it online!](https://tio.run/##KyxNTCn6/z8mOjouOlbbPlaP61FHl8aj3r5HXc2PevY@6t3qq/mod8ujribDR22TD603ApIgwf//o93y86OdEotijWONuKLz81JjDaNLyvNjjaJLMopSU2ONuSAMkCBEOtYIJKjooBytohoXraalARQwAmmOTsvPV0hKLALiKqAyQ5BxOZUK@XnJQF1GUF5JeSaQa2RsYmpmbmHJFV2UmptflqqQm6oYa8CVlJqWX5SqEJ2ZpxBrlJhWklr0/1HnQgA "QuadR – Try It Online")
`\[[^[]+?].` replace "`[`non-`[` stuff`]`character" with
`¯2↓⍵M` drop the last two characters of the **M**atch ("`]`digit")  
`1↓` drop the first character ("`[`")  
`⊂` enclose to be treated as a whole  
`(`…`)⍴` **r**eshape to length:  
 `⌽⍵M` reverse the **M**atch  
 `⊃` pick the first (the digit)  
 `⍎` evaluate  
`∊` **ϵ**nlist (flatten)
`≡` repeat until no more changes happen
---
The equivalent Dyalog APL function is 47 bytes:
```
'\[[^[]+?].'⎕R{∊(⍎⊃⌽⍵.Match)⍴⊂1↓¯2↓⍵.Match}⍣≡
```
[Try it online!](https://tio.run/##SyzI0U2pTMzJT///P@1R2wT1mOjouOhYbftYPfVHfVODqh91dGk86u171NX8qGfvo96ter6JJckZmo96tzzqajJ81Db50HojIAmXqX3Uu/hR50KgaQrq0W75@dFOiUWxxrFG6lwggfy81FjD6JLy/Fij6JKMotTUWGOIBJgDkoAoiTWCSSg6KEerqMZFq2lpAAWNYAZFp@XnKyQlFgFxFVC5Icz4nEqF/LxkoAlGSCIl5ZlAISNjE1MzcwtLiERRam5@WapCbqpirAFYJCk1Lb8oVSE6M08h1igxrSS1SB0A "APL (Dyalog Unicode) – Try It Online")
[Answer]
# Java 8, ~~250~~ ~~249~~ ~~241~~ 239 bytes
```
s->{for(;s.contains("[");)for(int i=0,j,k;i<s.length();)if(s.charAt(i++)==93){String t="",r=t;for(j=k=s.charAt(i)-48;j-->0;)t+=s.replaceAll(r="(.*)\\[([^\\]]+)\\]"+k+"(.*)","$2");s=k<1?t:s.replaceFirst(r,"$1$3").replace("",t);}return s;}
```
-2 bytes thanks to *@JonathanFrech* (code contains two unprintable ASCII characters now, which can be seen in the TIO-link below).
Sigh... Java with regex is so damn limited.. I'll just quote myself from another answer here:
> 
> *Replacing `WWWW` with `222W` is easy in Java, but with `4W` not..* If only Java had a way to use the regex capture-group for something.. Getting the length with `"$1".length()`, replacing the match itself with `"$1".replace(...)`, converting the match to an integer with `new Integer("$1")`, or using something similar as Retina (i.e. `s.replaceAll("(?=(.)\\1)(\\1)+","$#2$1"))` or JavaScript (i.e. `s.replaceAll("(.)\\1+",m->m.length()+m.charAt(0))`) would be my number 1 thing I'd like to see in Java in the future to benefit codegolfing.. >.> I think this is the 10th+ time I hate Java can't do anything with the capture-group match..  
> 
> [Quote from here.](https://codegolf.stackexchange.com/a/145775/52210)
> 
> 
> 
**Explanation:**
[Try it online.](https://tio.run/##jZNfb9sgFMXV134KyrIJ6j9K7G5rR@nWPfStfdkjoRJxcYPtQAQkVRf5s2c3qbu9LZGMhO89v8vhyG7UWmVuqW3z1G6rToWA7pWxm1OEjI3a16rS6GH3itCv6I19RhUZNoEyqPew4AlRRVOhB2QRR9uQ3Wxq5wkLeeVshImBYIEpo7sqTEaGj9MmbZm5Dnmn7XOcE@iamgAxV/42EpMklPOrkm6G8yLHOPU8st2Mhrf8n5RmF5esybKbMaMxgYbXyw6s33Yd8RyT/JxOp4KIx@lUygT2Eidtsq/jFI8KcBZ4ez35Hr/9Ze@MD5F4aE9ORiWm73WCT3AaKeu9jitvUWD9lr2FsFzNOghhyGLtzBNawN2HwIRUdEjyNUS9yN0q5kvoxM4Sm1eQ0J1z4qfyspRgaR/vf8TOajkR8cXJQsS511qWh6G9cAe94bI4Bjr78UGMPj6KT@cEgOIYc6J2Ds2Uh/Ubjpkcc53uFTlbgaviSHV8MSAvyovPX75eXh2GvF64tUYLfSbHB9UzDd@ZRsJYJAtVw88wIP1pv/0D)
```
s->{                           // Method with String as both parameter and return-type
  for(;s.contains("[");)       //  Loop as long as the String contains a block-bracket
    for(int i=0,j,k;i<s.length();)
                               //   Inner loop over the characters of the String
      if(s.charAt(i++)==93){   //    If the current character is a closing block-bracket:
        String t="",r=t;       //     Create two temp-Strings, starting empty
        for(j=k=s.charAt(i)-48;//     Take the digit after the closing bracket
            j-->0;)            //     Loop that many times:
          t+=s.replaceAll(r="(.*)\\[([^\\]]+)\\]"+k+"(.*)","$2");
                               //      Append `t` with the word inside the block brackets
        s=k<1?                 //     If the digit was 0:
           t                   //      Replace the input with an empty String as well
          :                    //     Else:
           s.replaceFirst(r,"$1$3").replace("",t);}
                               //      Replace the word between brackets by `t`,
                               //      and remove the digit
  return s;}                   //  Return the modified input-String as result
```
[Answer]
# [Wolfram Language (Mathematica)](https://www.wolfram.com/wolframscript/), 86 bytes
```
#//.s_:>StringReplace[s,"["~~x:Except["["|"]"]...~~"]"~~d_:>""<>x~Table~FromDigits@d]&
```
[Try it online!](https://tio.run/##RczbTsMwDAbgV/FSmBAqLcs4TlBVCHaNgDvLoLRzt0htM6URG6e8eslGJS4s2Z/tv1FuxY1yulR9BbfQR2madG@z7NlZ3S6feF2rkrGLBQrvt7OHbclrh2H6FiQoSRLvQ@P9IvwIcZNt/YsqavZza5p7vdSuyxc07h9DmsMoBgEnGYgYKoyIYAxpDl8C58bgnbI0JRl2Ak3LNEG3MSTRrSwzTfe@73f@d0Fy8FEe4cHhK46Pj4LJIQUrY6BQNtRnOJ4M0fUHmLYM7/If3EYHkdOz84vLq@u9W27MO0PDIzrdQcGVsQyoWyCpKsdW/PS/ "Wolfram Language (Mathematica) – Try It Online")
[Answer]
# C, ~~407~~ 368 bytes
Thanks to Jonathan Frech for saving bytes.
golfed (file bracket.c):
```
i,j,k,l,n;char*f(a,m)char*a;{for(i=0;a[i];++i){a[i]==91&&(j=i+1);if(a[i]==93){k=a[i+1]-48;if(!k){for(l=i+2;l<m;)a[++l-i+j-4]=a[l];a=realloc(a,m-3);return f(a,m-3);}for(l=j;l<i;)a[~-l++]=a[l];for(l=i+2;l<m;)a[++l-4]=a[l];m-=3;n=m+~-k*(i---j--);a=realloc(a,n);for(l=i;l<m;)a[l+++~-k*(i-j)]=a[l];for(m=0;m<k;++m)for(l=j;l<i;)a[l+++m*(i-j)]=a[l];return f(a,n);}}return a;}
```
ungolfed with program:
```
#include <stdlib.h>
#include <stdio.h>
// '[' = 133
// ']' = 135
// '0' = 48
i, j, k, l, n;
char* f(a,m) char*a;
{
  for (i=0; a[i]; ++i) {
    a[i]==91&&(j=i+1);
    if (a[i]==93) {
      k=a[i+1]-48;
      if (!k) {
        for (l=i+2; l<m; )
          a[++l-i+j-4] = a[l];
        a = realloc(a,m-3);
        return f(a,m-3);
      }
      for (l=j;l<i;)
        a[~-l++] = a[l];
      for (l=i+2; l<m; )
        a[++l-4] = a[l];
      m -= 3;
      n = m+~-k*(i---j--);
      a = realloc(a,n);
      for (l=i; l<m; )
        a[l+++~-k*(i-j)] = a[l];
      for (m=0; m<k; ++m)
        for (l=j; l<i;)
          a[l+++m*(i-j)] = a[l];
      return f(a,n);
    }
  }
  return a;
}
int main()
{
  char c[]="[Foo[Bar]3]2";
  char *b;
  char cc[]="[remove me!]0";
  char *bb;
  char ccc[]="[only once]12";
  char *bbb;
  b=malloc(13);
  bb=malloc(14);
  bbb=malloc(14);
  for (i=0; i<13; ++i)
    b[i] = c[i];
  for (i=0; i<14; ++i)
    bb[i] = cc[i];
  for (i=0; i<14; ++i)
    bbb[i]=ccc[i];
  printf("%s\n", f(b, 13));
  printf("%s\n", f(bb, 14));
  printf("%s\n", f(bbb, 14));
  return 0;
}
```
Compiled with gcc 5.4.1, `gcc bracket.c`
[Answer]
# [Red](http://www.red-lang.org), 147 bytes
```
f: func[t][a: charset[not"[]"]while[parse t[any a some[remove["["copy h any a"]"copy d a](insert/dup v: copy""h to-integer d)insert v | skip]]][]t]
```
Ungolfed:
```
f: func [t][
    a: charset [not "[]"]                          ; all chars except [ and ]
    while [ parse t [                              ; repeat while parse is returning true
        any a                                      ; 0 or more chars other than [ and ]
        some [                                     ; one or more block:
            remove ["[" copy h any a "]" copy d a] ; remove the entire block, store the
                                                   ; substring between the [] in h,
                                                   ; the digit into d
            (insert/dup v: copy "" h to-integer d) ; makes d copies of h 
            insert v                               ; and inserts them in place 
            | skip ]                               ; skip if no match
        ]                                       
    ][]                                            ; empty block for 'while'
    t                                              ; return the modified string
]
```
I started learning Red's Parse dialect only yesterday, so I'm sure my code can be improved further. Parse is incomparably more verbose than regex, but is very clear, flexible and readable and can be freely mixed with the rest of the Red language.
[Try it online!](https://tio.run/##ZZDLTsMwEEX3fMXUPFSQENTh2RViwQewHU0lNxmTiMYTOdNUQfx7cJsFqaqRF3PO9bXkyMXwyQUgDX4JfhtyVEK3hLx0sWXFIGqQDO3KasPY7CEoutCDg1Zqxsi1dIwGTS5NDyUcnKFxLcDRvAotR70rtg10qTlxY0pQua2C8hdHKK7HCHTwC@131RARktLQxBQBDwY/RPDdRcrImrN/LIFpgboTsqhlZKZsqg9or8cg2WM9ezvHi8vVCq9u5smlMTDR6EVg7WI6P@ny4vjhTQ8S8tRqT7juqiRs9vD49PzyOtXjb0HNM7qf8DV7iQxYBSDrvHI0wx8 "Red – Try It Online")
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 30 bytes
```
œṡ”]µḢUœṡ”[ẋ€1¦Ṫ©Ḣ$FṚ;®
Çċ”]$¡
```
[Try it online!](https://tio.run/##y0rNyan8///o5Ic7Fz5qmBt7aOvDHYtCYdzoh7u6HzWtMTy07OHOVYdWAqVU3B7unGV9aB3X4fYj3SANKocW/v//Pzr6UdskMNoeawKlLQE "Jelly – Try It Online")
---
## Explanation.
```
œṡ”]µḢUœṡ”[ẋ€1¦Ṫ©Ḣ$FṚ;®    Helper link 1, expand once.
                           Assume input = "ab[cd]2ef".
œṡ      Split at first occurence of
  ”]      character "]".
    µ   Start new monadic chain. Value = "ab[cd","2ef".
Ḣ       **Ḣ**ead. "ab[cd"
 U      **U**pend. "dc[ba"
  œṡ”[  Split at first occurence of "[". | "dc","ba".
ẋ€        Repeat ...
  1¦        the element at index **1**...
          by ...
    Ṫ Ḣ$    the **Ḣ**ead of the **Ṫ**ail of ...
          the input list ("ab[cd","2ef") (that is, 2)
          The command **Ḣ** also pop the head '2'. The remaining
            part of the tail is "ef".
     ©    Meanwhile, store the tail ("ef") to the register.
          Current value: "dcdc","ba"
FṚ        **F**latten and **Ṛ**everse. | "abcdcd"
  ;®      Concatenate with the value of the register. "abcdcdef"
Çċ”]$¡    Main link.
 ċ”]$     Count number of "]" in the input.
     ¡    Repeatedly apply...
Ç           the last link...
            that many times.
```
[Answer]
# C,381 bytes
Compact version:
```
while(1){int t=strlen(i);int a,c=-1;char*w;char*s;char*f;while(c++<t){if(i[c]==']'){int k=c-a;w=calloc((k--),1);memcpy(w,&i[a+1],k);s=calloc((t-c-1),1);memcpy(s,&i[c+2],t-c-2);i[a]=0;int r=i[c+1]-48;if(r==0){f=calloc(t,1);sprintf(f,"%s%s",i,s);}else{f=calloc((t+k),1);sprintf(f,"%s%s[%s]%d%s",i,w,w,r-1,s);}free(i);i=f;break;}else if(i[c]=='[')a=c;}free(w);free(s);if(c>=t)break;}
```
Full version:
```
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
void proceed(char* input)
{
  while(1)
  {
    int t=strlen(input);
    int start,cursor=-1;
    char* word;
    char* suffix;
    char* final;
    while(cursor++<t)
    {
      if(input[cursor]==']')
      {
        int wordlength = cursor-start;
        word=calloc((wordlength--),sizeof(char));
        memcpy(word, &input[start+1], wordlength );
        suffix=calloc((t-cursor-1),sizeof(char));
        memcpy( suffix, &input[cursor+2], t-cursor-2 );
        input[start]='\0';
        int rep=input[cursor+1]-'0';
        if(rep==0)
        {
          final=calloc(t,sizeof(char));
          sprintf(final,"%s%s",input,suffix);
        }
        else
        {
          final=calloc((t+wordlength+5),sizeof(char));
          sprintf(final,"%s%s[%s]%d%s",input,word,word,rep-1,suffix);
        }
        free(input);
        input=final;
        break;
      }
      else if(input[cursor]=='[')
        start=cursor;
    }
    free(word);
    free(suffix);
    if(cursor>=t)break;
  }
}
int main()
{
  char* input=calloc(256,sizeof(char));
  sprintf(input,"a[[toto]2b]2[ana]3");
  printf("in : %s\n",input);
  proceed(input);
  printf("out: %s\n",input);
  return 0;
}
```
]