VB .NET - Usando Expressões regulares(Regex)


Eu já escrevi diversos artigos sobre o recurso Regex para saber mais leia os artigos:

Este artigo mostra como usar as expressões regulares para realizar validações.

Em todas as validações a estrutura básica é a mesma e segue o seguinte raciocínio:

1 - Primeiro definimos a expressão regular que será usada para realizar a validação

Dim padraoRegex As String = " expressão regular "

Aqui eu pesquisei na web e encontrei as expressões usadas para as diversas validações.

2 - A seguir criamos uma instância do objeto Regex usando a expressão regular definida

Dim verifica As New RegularExpressions.Regex(padraoRegex, RegexOptions.IgnorePatternWhitespace)

A classe Regex representa o mecanismo para tratar as expressões regulares na plataforma .NET . Ela pode ser usado para analisar rapidamente grandes quantidades de texto para encontrar padrões de caracteres específicos; para extrair, editar, substituir ou excluir substrings de texto, ou para adicionar as strings extraídas a uma coleção para gerar um relatório.

Para usar as expressões regulares, definimos o padrão desejado para identificar em um fluxo de texto usando a sintaxe documentada nos Elementos de linguagem das expressões regulares. A seguir instanciamos um objeto Regex. Finalmente, executamos alguma operação, como a substituição de texto que corresponda ao padrão de expressão regular, ou a identificação de um padrão coincidente.

A enumeração RegexOptions Fornece valores enumerados para usar para definir opções de expressões regulares. Os valores possíveis são:

Valor Descrição
None Especifica que nenhuma opção foi definida
IgnoreCase Especifica a comparação case-sensitive
ExplicitCapture Especifica que as únicas capturas válidas são explicitamente nomeadas ou grupos numerados do formulário (? <name> ...).
Isso permite que os parênteses sem nome atuem como grupos de não captura, sem a deselegância sintática da expressão (:? ...).
Singleline Especifica modo linha-única. Muda o significado do ponto (.) Para que coincida com todos os caracteres (em vez de cada caractere, exceto \ n).
IgnorePatternWhitespace Elimina espaços em branco sem escape do padrão e permite comentários marcados com #. No entanto, o valor IgnorePatternWhitespace não  afeta ou elimina o espaço em branco nas classes de caracteres.
ECMAScript Permite o comportamento compatível com ECMAScript para a expressão. Este valor pode ser usado apenas em conjunto com os valores IgnoreCase, Multiline, e Compiled. A utilização deste valor com quaisquer outros valores gera uma excepção.
CultureInvariant Especifica que as diferenças culturais na linguagem será ignorada.
Compiled Especifica que a expressão regular é compilada para um assembly. Isto obtém um rendimento melhor na execução, mas aumenta o tempo de inicialização. Este valor não deve ser atribuído à propriedade Opções ao chamar o método CompileToAssembly.
Multiline Modo multilinha. Altera o significado de ^ e $ para que eles correspondam ao início e final, respectivamente, de qualquer linha, e não apenas  o início e o fim de toda a cadeia.
RightToLeft Especifica que a pesquisa será da direita para a esquerda em vez de da esquerda para a direita.

Na aplicação exemplos iremos realizar as seguintes validações :

Validação Expressão Regular
Email ^[-a-zA-Z0-9][-.a-zA-Z0-9]*@[-.a-zA-Z0-9]+(\.[-.a-zA-Z0-9]+)*\.(com|edu|info|gov|int|mil|net|org|biz|name|museum|coop|aero|pro|tv|[a-zA-Z]{2})$
IP ^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$
Cep ^\d{5}-\d{3}$
Telefone ^[0-9]{2}-[0-9]{4}-[0-9]{4}$
Data (dd/mm/yyyy) ^((0[1-9]|[12]\d)\/(0[1-9]|1[0-2])|30\/(0[13-9]|1[0-2])|31\/(0[13578]|1[02]))\/\d{4}$ ou ^([0]?[1-9]|[1|2][0-9]|[3][0|1])[./-]([0]?[1-9]|[1][0-2])[./-]([0-9]{4}|[0-9]{2})$
URL ^((http)|(https)|(ftp)):\/\/([\- \w]+\.)+\w{2,3}(\/ [%\-\w]+(\.\w{2,})?)*$
CPF ^(\d{3}.\d{3}.\d{3}-\d{2})|(\d{11})$ ou ^\d{3}\x2E\d{3}\x2E\d{3}\x2D\d{2}$
CNPJ ^\d{3}.?\d{3}.?\d{3}/?\d{3}-?\d{2}$ ou ^\d{2}\.\d{3}\.\d{3}\/\d{4}\-\d{2}$
Somente números ^[0-9]*$

Você pode procurar por expressões regulares no link: http://regexlib.com/Search.aspx

Criando o projeto VB .NET

Abra o Visual Basic 2010 Express Edition e no menu File clique em New Project informando o nome ValidarComRegex e no formulário padrão inclua uma Label, uma caixa de Texto, um Button e 9 controles radiobuttons conforme o leiaute da figura abaixo:

A seguir no menu Project clique em Add Class e informe o nome Validar.vb incluindo o código abaixo nesta classe:

Imports System.Text
Imports System.Text.RegularExpressions

Public Class Validar

    ''' <param name="email">email para validar</param>
    ''' <returns>true é valido , false é inválido</returns>
    Public Shared Function IsValidEmail(ByVal email As String) As Boolean
        Dim padraoRegex As String = "^[-a-zA-Z0-9][-.a-zA-Z0-9]*@[-.a-zA-Z0-9]+(\.[-.a-zA-Z0-9]+)*\." & _
        "(com|edu|info|gov|int|mil|net|org|biz|name|museum|coop|aero|pro|tv|[a-zA-Z]{2})$"
        Dim verifica As New RegularExpressions.Regex(padraoRegex, RegexOptions.IgnorePatternWhitespace)
       Dim valida As Boolean = False
        'verifica se foi informado um email
        If String.IsNullOrEmpty(email) Then
            valida = False
        Else
            'usar IsMatch para validar o email
            valida = verifica.IsMatch(email)
        End If
        'retorna o valor
        Return valida
    End Function
    Public Shared Function IsValidIP(ByVal ip As String) As Boolean
        'cria o padrão regex
        Dim padraoRegex As String = "^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\." & _
        "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$"
        'cria o objeto Regex
        Dim verifica As New RegularExpressions.Regex(padraoRegex)
        'variavel boolean para tratar o status
        Dim valida As Boolean = False
        'verifica se o recurso foi fornecido
        If ip = "" Then
            'ip invalido
            valida = False
        Else
            'usa o método IsMatch Method para validar o regex
            valida = verifica.IsMatch(ip, 0)
        End If
        Return valida
    End Function
    Public Shared Function isValidCep(ByVal cep As String) As Boolean
        'cria o padrão regex
        Dim padraoRegex As String = "^\d{5}-\d{3}$"
        Dim verifica As New RegularExpressions.Regex(padraoRegex)
        'variavel boolean para tratar o status
        Dim valida As Boolean = False
        'verifica se o recurso foi fornecido
        If cep = "" Then
            'cep invalido
            valida = False
        Else
            'usa o método IsMatch Method para validar o regex
            valida = verifica.IsMatch(cep, 0)
        End If
        Return valida
    End Function
    Public Shared Function isValidSoNumeros(ByVal sonumeros As String) As Boolean
        'cria o padrão regex
        Dim padraoRegex As String = "^[0-9]*$"
        Dim verifica As New RegularExpressions.Regex(padraoRegex)
        'variavel boolean para tratar o status
        Dim valida As Boolean = False
        'verifica se o recurso foi fornecido
        If sonumeros = "" Then
            'cep invalido
            valida = False
        Else
            'usa o método IsMatch Method para validar o regex
            valida = verifica.IsMatch(sonumeros, 0)
        End If
        Return valida
    End Function
    Public Shared Function isValidTelefone(ByVal telefone As String) As Boolean
        'cria o padrão regex
        '^\d{2}-\d{4}-\d{4}$ 
        Dim padraoRegex As String = "^[0-9]{2}-[0-9]{4}-[0-9]{4}$"
        'cria o objeto Regex
        Dim verifica As New RegularExpressions.Regex(padraoRegex)
        'variavel boolean para tratar o status
        Dim valida As Boolean = False
        'verifica se o recurso foi fornecido
        If telefone = "" Then
            'telefone invalido
            valida = False
        Else
            'usa o método IsMatch Method para validar o regex
            valida = verifica.IsMatch(telefone, 0)
        End If
        Return valida
    End Function
    Public Shared Function isValidDataDDMMYYYY(ByVal ddmmyyyy As String) As Boolean
        'cria o padrão regex
        Dim padraoRegex As String = "^((0[1-9]|[12]\d)\/(0[1-9]|1[0-2])|30\/(0[13-9]|1[0-2])|31\/(0[13578]|1[02]))\/\d{4}$"
        Dim verifica As New RegularExpressions.Regex(padraoRegex)
        'variavel boolean para tratar o status
        Dim valida As Boolean = False
        'verifica se o recurso foi fornecido
        If ddmmyyyy = "" Then
            'telefone invalido
            valida = False
        Else
            'usa o método IsMatch Method para validar o regex
            valida = verifica.IsMatch(ddmmyyyy, 0)
        End If
        'return the results
        Return valida
    End Function
    Public Shared Function isValidUrl(ByVal url As String) As Boolean
        'cria o padrão regex
        Dim padraoRegex As String = "^((http)|(https)|(ftp)):\/\/([\- \w]+\.)+\w{2,3}(\/ [%\-\w]+(\.\w{2,})?)*$"
        Dim verifica As New RegularExpressions.Regex(padraoRegex)
        Dim valida As Boolean = False
        If url = "" Then
            'telefone invalido
            valida = False
        Else
            valida = verifica.IsMatch(url, 0)
        End If
        Return valida
    End Function
    Public Shared Function isValidCNPJ(ByVal cnpj As String) As Boolean
        Dim padraoRegex As String = "^\d{2}\.\d{3}\.\d{3}\/\d{4}\-\d{2}$"
        Dim verifica As New RegularExpressions.Regex(padraoRegex)
        Dim valida As Boolean = False
        If cnpj = "" Then
            valida = False
        Else
            valida = verifica.IsMatch(cnpj, 0)
        End If
        Return valida
    End Function
    Public Shared Function ValidarCpf(ByVal cpf As String) As Boolean
        cpf = cpf.Replace("-", "")
        cpf = cpf.Replace(".", "")

        Dim reg As New Regex("(^(\d{3}.\d{3}.\d{3}-\d{2})|(\d{11})$)")
        If Not reg.IsMatch(cpf) Then
            Return False
        End If

        Dim d1 As Integer, d2 As Integer
        Dim soma As Integer = 0
        Dim digitado As String = ""
        Dim calculado As String = ""

        ' Pesos para calcular o primeiro digito
        Dim peso1 As Integer() = New Integer() {10, 9, 8, 7, 6, 5, 4, 3, 2}

        ' Pesos para calcular o segundo digito
        Dim peso2 As Integer() = New Integer() {11, 10, 9, 8, 7, 6, 5, 4, 3, 2}

        Dim n As Integer() = New Integer(10) {}

        Dim retorno As Boolean = False

        ' Limpa a string
        cpf = cpf.Replace(".", "").Replace("-", "").Replace("/", "").Replace("\", "")

        ' Se o tamanho for < 11 entao retorna como inválido
        If cpf.Length <> 11 Then
            Return False
        End If

        ' Caso coloque todos os numeros iguais
        Select Case cpf

            Case "11111111111"
                Return False
            Case "00000000000"
                Return False
            Case "2222222222"
                Return False
            Case "33333333333"
                Return False
            Case "44444444444"
                Return False
            Case "55555555555"
                Return False
            Case "66666666666"
                Return False
            Case "77777777777"
                Return False
            Case "88888888888"
                Return False
            Case "99999999999"
                Return False
        End Select

        Try
            ' Quebra cada digito do CPF
            n(0) = Convert.ToInt32(cpf.Substring(0, 1))
            n(1) = Convert.ToInt32(cpf.Substring(1, 1))
            n(2) = Convert.ToInt32(cpf.Substring(2, 1))
            n(3) = Convert.ToInt32(cpf.Substring(3, 1))
            n(4) = Convert.ToInt32(cpf.Substring(4, 1))
            n(5) = Convert.ToInt32(cpf.Substring(5, 1))
            n(6) = Convert.ToInt32(cpf.Substring(6, 1))
            n(7) = Convert.ToInt32(cpf.Substring(7, 1))
            n(8) = Convert.ToInt32(cpf.Substring(8, 1))
            n(9) = Convert.ToInt32(cpf.Substring(9, 1))
            n(10) = Convert.ToInt32(cpf.Substring(10, 1))
        Catch
            Return False
        End Try

        ' Calcula cada digito com seu respectivo peso
        For i As Integer = 0 To peso1.GetUpperBound(0)
            soma += (peso1(i) * Convert.ToInt32(n(i)))
        Next

        ' Pega o resto da divisao
        Dim resto As Integer = soma Mod 11

        If resto = 1 OrElse resto = 0 Then
            d1 = 0
        Else
            d1 = 11 - resto
        End If

        soma = 0

        ' Calcula cada digito com seu respectivo peso
        For i As Integer = 0 To peso2.GetUpperBound(0)
            soma += (peso2(i) * Convert.ToInt32(n(i)))
        Next

        ' Pega o resto da divisao
        resto = soma Mod 11

        If resto = 1 OrElse resto = 0 Then
            d2 = 0
        Else
            d2 = 11 - resto
        End If

        calculado = d1.ToString() + d2.ToString()
        digitado = n(9).ToString() + n(10).ToString()

        ' Se os ultimos dois digitos calculados bater com
        ' os dois ultimos digitos do cpf entao é válido
        If calculado = digitado Then
            retorno = True
        Else
            retorno = False
        End If

        Return retorno
    End Function
End Class

A seguir no evento Click do botão de comando Validar inclua o código abaixo:

Public Class Form1

    Private Sub btnValidar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnValidar.Click

        If rdbCEP.Checked Then
            If Validar.isValidCep(txtDados.Text) Then
                MessageBox.Show("CEP valido...", "VÁLIDO", MessageBoxButtons.OK, MessageBoxIcon.Information)
            Else
                MessageBox.Show("CEP inválido...", "INVÁLIDO", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End If
        ElseIf rdbCNPJ.Checked Then
            If Validar.isValidCNPJ(txtDados.Text) Then
                MessageBox.Show("CNPJ valido...", "VÁLIDO", MessageBoxButtons.OK, MessageBoxIcon.Information)
            Else
                MessageBox.Show("CNPJ inválido...", "INVÁLIDO", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End If
        ElseIf rdbCPF.Checked Then
            If Validar.ValidarCpf(txtDados.Text) Then
                MessageBox.Show("CPF valido...", "VÁLIDO", MessageBoxButtons.OK, MessageBoxIcon.Information)
            Else
                MessageBox.Show("CPF inválido...", "INVÁLIDO", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End If
        ElseIf rdbData.Checked Then
            If Validar.isValidDataDDMMYYYY(txtDados.Text) Then
                MessageBox.Show("Data valido...", "VÁLIDO", MessageBoxButtons.OK, MessageBoxIcon.Information)
            Else
                MessageBox.Show("Data inválido...", "INVÁLIDO", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End If
        ElseIf rdbEmail.Checked Then
            If Validar.IsValidEmail(txtDados.Text) Then
                MessageBox.Show("Email valido...", "VÁLIDO", MessageBoxButtons.OK, MessageBoxIcon.Information)
            Else
                MessageBox.Show("Email inválido...", "INVÁLIDO", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End If
        ElseIf rdbFone.Checked Then
            If Validar.isValidTelefone(txtDados.Text) Then
                MessageBox.Show("Telefone valido...", "VÁLIDO", MessageBoxButtons.OK, MessageBoxIcon.Information)
            Else
                MessageBox.Show("Telefone inválido...", "INVÁLIDO", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End If
        ElseIf rdbIP.Checked Then
            If Validar.IsValidIP(txtDados.Text) Then
                MessageBox.Show("IP valido...", "VÁLIDO", MessageBoxButtons.OK, MessageBoxIcon.Information)
            Else
                MessageBox.Show("IP inválido...", "INVÁLIDO", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End If
        ElseIf rdbURL.Checked Then
            If Validar.isValidUrl(txtDados.Text) Then
                MessageBox.Show("URL valido...", "VÁLIDO", MessageBoxButtons.OK, MessageBoxIcon.Information)
            Else
                MessageBox.Show("URL inválido...", "INVÁLIDO", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End If
        ElseIf rdbSoNumeros.Checked Then
            If Validar.isValidSoNumeros(txtDados.Text) Then
                MessageBox.Show("dados valido...", "VÁLIDO", MessageBoxButtons.OK, MessageBoxIcon.Information)
            Else
                MessageBox.Show("dados inválido...", "INVÁLIDO", MessageBoxButtons.OK, MessageBoxIcon.Error)
            End If
        End If
    End Sub
End Class

O código usado é funcional mas esta longe das melhores práticas. É um código básico, de fácil entendimento e estruturado para iniciantes.

Eu não precisaria repetir o código para validar cada recurso usando métodos distintos poderia criar um método único usando os recursos da orientação a objetos da linguagem VB .NET.

Deixo isso como um exercício para você.

Pegue o projeto completo aqui: ValidarComRegex.zip

Rom 3:10 como está escrito: Não há justo, nem sequer um.

Rom 3:11 Não há quem entenda; não há quem busque a Deus.

Rom 3:12 Todos se extraviaram; juntamente se fizeram inúteis. Não há quem faça o bem, não há nem um só.

Referências:


José Carlos Macoratti