Innanzitutto dovrebbe valere pure la regola che più coppie di parentesi non possono "sovrapporsi" (come per i tag XML). Ovvero in ([)] le coppie loro stesse sono ok ma si sovrappongono e quindi non è valido.
Comunque per la scansione della stringa basta un semplice for ma quello che è importante è la logica di analisi.
Per fare la cosa in modo pulito e lineare dovresti usare uno "stack" di caratteri. Quando trovi una parentesi di apertura la "spingi" sullo stack. Quando ne trovi una di chiusura, se corrisponde a quella che appare al top dello stack, allora la togli dallo stack. Se alla fine di tutti i caratteri lo stack è vuoto, allora le parentesi sono bilanciate.
P.S. si può fare anche con un approccio "ricorsivo". Devi valutare tu in base a cosa ti è stato eventualmente imposto o suggerito.