Task: Brace expansion







Python: def getitem(s, depth=0):
    out = [""]
    while s:
        c = s[0]
        if depth and (c == ',' or c == '}'):
            return out,s
        if c == '{':
            x = getgroup(s[1:], depth+1)
            if x:
                out,s = [a+b for a in out for b in x[0]], x[1]
                continue
        if c == '\\' and len(s) > 1:
            s, c = s[1:], c + s[1]

        out, s = [a+c for a in out], s[1:]

    return out,s

def getgroup(s, depth):
    out, comma = [], False
    while s:
        g,s = getitem(s, depth)
        if not s: break
        out += g

        if s[0] == '}':
            if comma: return out, s[1:]
            return ['{' + a + '}' for a in out], s[1:]

        if s[0] == ',':
            comma,s = True, s[1:]

    return None


for s in .split('\n'):
    print "\n\t".join([s] + getitem(s)[0]) + "\n"


VB: Module Module1

    Function GetGroup(s As String, depth As Integer) As Tuple(Of List(Of String), String)
        Dim out As New List(Of String)
        Dim comma = False
        While Not String.IsNullOrEmpty(s)
            Dim gs = GetItem(s, depth)
            Dim g = gs.Item1
            s = gs.Item2
            If String.IsNullOrEmpty(s) Then
                Exit While
            End If
            out.AddRange(g)

            If s(0) = "}" Then
                If comma Then
                    Return Tuple.Create(out, s.Substring(1))
                End If
                Return Tuple.Create(out.Select(Function(a) "{" + a + "}").ToList(), s.Substring(1))
            End If

            If s(0) = "," Then
                comma = True
                s = s.Substring(1)
            End If
        End While
        Return Nothing
    End Function

    Function GetItem(s As String, Optional depth As Integer = 0) As Tuple(Of List(Of String), String)
        Dim out As New List(Of String) From {""}
        While Not String.IsNullOrEmpty(s)
            Dim c = s(0)
            If depth > 0 AndAlso (c = "," OrElse c = "}") Then
                Return Tuple.Create(out, s)
            End If
            If c = "{" Then
                Dim x = GetGroup(s.Substring(1), depth + 1)
                If Not IsNothing(x) Then
                    Dim tout As New List(Of String)
                    For Each a In out
                        For Each b In x.Item1
                            tout.Add(a + b)
                        Next
                    Next
                    out = tout
                    s = x.Item2
                    Continue While
                End If
            End If
            If c = "\" AndAlso s.Length > 1 Then
                c += s(1)
                s = s.Substring(1)
            End If
            out = out.Select(Function(a) a + c).ToList()
            s = s.Substring(1)
        End While
        Return Tuple.Create(out, s)
    End Function

    Sub Main()
        For Each s In {
            "It{{em,alic}iz,erat}e{d,}, please.",
            "~/{Downloads,Pictures}/*.{jpg,gif,png}",
            "{,{,gotta have{ ,\, again\, }}more }cowbell!",
            "{}} some }{,{\\{ edge, edge} \,}{ cases, {here} \\\\\}"
        }
            Dim fmt = "{0}" + vbNewLine + vbTab + "{1}"
            Dim parts = GetItem(s)
            Dim res = String.Join(vbNewLine + vbTab, parts.Item1)
            Console.WriteLine(fmt, s, res)
        Next
    End Sub

End Module