Regex: o usuário deve inserir a primeira letra maiúscula [Resolvido]

Edit: O tópico apareceu duas vezes no fórum porque ao enviar a mensagem apareceu uma exceção de ArrayIndexOutOfBoundsException e então tentei enviar a mensagem de novo.

Boa tarde. Eu criei uma regex que deve coincidir com um nome com a primeira letra maiúscula e achei que a tinha escrito corretamente. Vocês poderiam me dizer qual regex eu poderia escrever para o padrão “Nome com a primeira letra maiúscula”? obrigado.


public class Validator
{
    public static String validateName(String name)
    {
        String reg1 = "^([A-Z]{1})([a-z]{1,})$";
        if(name.matches(reg1))
        {
          return name;	
        }
        else {
         return "";	
        }
    }	
}
import java.util.regex.*;

class PrimeiraLetraMaiuscula {
    private static Pattern patNomeValido = Pattern.compile ("\p{Lu}[\p{L}\s'.]*");
    public static String nomeValido (final String nome) {
	    if (patNomeValido.matcher (nome).matches()) {
		    return nome;
		} else {
		    return "";
		}
	}
    public static void main (String[] args) {
	    String[] nomes = {
		    "Dilma Vana Rousseff",
			"d'Alembert",
			"di Cavalcanti",
			"D. Pedro II",
			"Gisele Bündchen",
			"Alessandra D'Ambrósio",
		};
		for (String nome : nomes) {
		    System.out.printf ("%s --> %s %n", nome, nomeValido (nome));
		}
	}
}

Cara, tu pode explicar a ideia ai do teu regex? O que o “\p” “{Lu}” e etc fazem.

Abraços,

http://download.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html

\p{Lu} -> letras maiúsculas (inclui letras acentuadas)
\p{L} -> letras (inclui letras acentuadas)
\s -> espaços

Só me explica duas coisas por favor: por que escrever um regex como no javascript não funciona se na classe Pattern especifica que [a-z] é o intervalo para as letras minúsculas e [A-Z] para maiúsculas, etc ?

Não seria mais simples fazer uma simples comparação com matches? por que tem que passar por todo o processo de compilação (com compile() ) de regex e etc ?

  1. Bom, eu lembrei que há aquele maldito problema das letras acentuadas (Á, É etc. ) que não estão no intervalo [A-Z].
    Se você não precisa de letras acentuadas (mas você mencionou “nomes”, portanto escrevi um que bate com nomes de gente, que costumam ter apóstrofos, pontos, letras acentuadas e outras coisas mais esquisitas).
  2. Eu usei uma otimização que pode ser interessante se você precisar bater com muitos nomes com a máxima eficiência. String.matches() é um método que deve ser usado apenas se você tiver certeza que vai ser usado poucas vezes, já que ele é basicamente isto:

“x”.matches(“y”) == Pattern.compile(“y”).matcher(“x”).matches()

(veja a definição do método “String.matches” no fonte do JDK)

e o processo de compilação de uma expressão regular é razoavelmente lento. (No C#, há um caso até em que se gera um método dinamicamente, com os bytecodes correspondentes à interpretação de uma expressão regular. Não sei se no caso do Java é apenas uma tabela com a expressão compilada.