/* http://pt.stackoverflow.com/q/177044/53463 */

import java.util.regex.Matcher;
import java.util.regex.Pattern;

class Ideone
{
	public static void main (String[] args) throws java.lang.Exception
	{
		final String regex = "\\G"                    // Início do texto ou fim do casamento anterior
		                   + "[^\\[']*"               // Texto sem colchetes nem aspas simples
		                   + "(?:'[^']*'[^\\['*]*)*"  // Opcional: Texto em aspas + texto sem "[" nem "'"
		                   + "(\\["                   // Grupo 1: Colchete de abertura
		                   +     "[^]']*"             //        + texto sem "]" nem "'"
		                   +     "(?:'[^']*'[^]']*)*" //        + texto em aspas + texto sem "]" nem "'"
		                   + "\\])";                  //        + colchete de fechamento
		final Pattern pat = Pattern.compile(regex);
		Matcher mat;
		
		final String[] entrada = {
		    "1 + [aa]",
		    "[bb] + 2",
		    "'a' + [cc]",
		    "['ola' + 'mundo']",
		    "'[a' + 'b]'",
		    "'[' + ']'",
		    "[]",
		    "'Ola [world] legal'",
		    "Oi ['[aa]'] ola"
		};
		
		//Loop cada string na entrada
		for (String stringlToVerify :  entrada) {
		    mat = pat.matcher(stringlToVerify);
		    System.out.println("\nEntrada: " + stringlToVerify);
		
		    if (mat.find())
		        do { // Loop cada texto entre colchetes casado
		            System.out.println("Captura: " + mat.group(1));
		        } while (mat.find());
		    else
		        System.out.println("Não há colchetes fora das aspas");
		}
	}
}