Cómo comprobar si las cadenas tienen un formato de correo electrónico válido

En el ejemplo de este artículo se usa una expresión regular para comprobar que una cadena tiene un formato de correo electrónico válido.

Esta expresión regular es comparativamente más sencilla de lo que se puede usar realmente como un correo electrónico. Usar una expresión regular para validar un correo electrónico es útil para asegurarse de que la estructura del correo electrónico es correcta. Pero no sustituye a la comprobación de que el correo electrónico existe realmente.

✔️ Use una expresión regular pequeña para comprobar si la estructura de un correo electrónico es válida.

✔️ Envíe un correo electrónico de prueba a la dirección proporcionada por un usuario de su aplicación.

❌ No use una expresión regular como la única manera de validar un correo electrónico.

Si intenta crear la expresión regular perfecta para validar que la estructura de un correo electrónico es correcta, la expresión se vuelve tan compleja que es increíblemente difícil de depurar o mejorar. Las expresiones regulares no pueden validar la existencia de un correo electrónico, incluso aunque esté estructurado correctamente. La mejor manera de validar un correo electrónico es enviar un mensaje de correo electrónico de prueba a la dirección.

Advertencia

Cuando se usa System.Text.RegularExpressions para procesar entradas que no son de confianza, pase un tiempo de expiración. Un usuario malintencionado puede proporcionar entradas a RegularExpressions y provocar un ataque por denegación de servicio. Las API del marco ASP.NET Core en las que se usa RegularExpressions pasan un tiempo de expiración.

Ejemplo

En el ejemplo se define un método IsValidEmail, que devuelve true si la cadena contiene una dirección de correo electrónico válida y false si no es válida, pero no realiza ninguna otra acción.

Para comprobar que la dirección de correo electrónico es válida, el método IsValidEmail llama al método Regex.Replace(String, String, MatchEvaluator) con el patrón de expresión regular (@)(.+)$ para separar el nombre de dominio de la dirección de correo electrónico. El tercer parámetro es un delegado MatchEvaluator que representa el método que procesa y reemplaza el texto coincidente. El patrón de expresión regular se interpreta de la siguiente manera:

Modelo Descripción
(@) Buscar el carácter @. Esta parte es el primer grupo de captura.
(.+) Buscar una coincidencia con una o más apariciones de cualquier carácter. Esta parte es el segundo grupo de captura.
$ Finalizar la búsqueda al final de la cadena.

El nombre de dominio, junto con el carácter @, se pasa al método DomainMapper. El método usa la clase IdnMapping para trasladar los caracteres Unicode fuera del intervalo de caracteres US-ASCII a Punycode. El método también establece la marca invalid en True si el método IdnMapping.GetAscii detecta cualquier carácter no válido en el nombre del dominio. El método devuelve el nombre de dominio Punycode precedido por el símbolo @ al método IsValidEmail .

Sugerencia

Se recomienda usar el patrón de expresión regular simple (@)(.+)$ para normalizar el dominio y devolver un valor que indique si el resultado ha sido correcto o se ha producido un error. Pero en el ejemplo de este artículo se describe cómo usar de forma avanzada una expresión regular para validar el correo electrónico. Independientemente de cómo valide un correo electrónico, siempre debe enviar un correo electrónico de prueba a la dirección para asegurarse de que existe.

A continuación, el método IsValidEmail llama al método Regex.IsMatch(String, String) para comprobar que la dirección se ajusta a un patrón de expresión regular.

El método IsValidEmail simplemente determina si el formato del correo electrónico es válido para una dirección de correo electrónico, no valida si el correo electrónico existe. Además, el método IsValidEmail no comprueba que el nombre del dominio de nivel superior sea un nombre válido enumerado en la base de datos de la zona de la raíz de IANA, lo cual requeriría una operación de búsqueda.

using System;
using System.Globalization;
using System.Text.RegularExpressions;

namespace RegexExamples
{
    class RegexUtilities
    {
        public static bool IsValidEmail(string email)
        {
            if (string.IsNullOrWhiteSpace(email))
                return false;

            try
            {
                // Normalize the domain
                email = Regex.Replace(email, @"(@)(.+)$", DomainMapper,
                                      RegexOptions.None, TimeSpan.FromMilliseconds(200));

                // Examines the domain part of the email and normalizes it.
                string DomainMapper(Match match)
                {
                    // Use IdnMapping class to convert Unicode domain names.
                    var idn = new IdnMapping();

                    // Pull out and process domain name (throws ArgumentException on invalid)
                    string domainName = idn.GetAscii(match.Groups[2].Value);

                    return match.Groups[1].Value + domainName;
                }
            }
            catch (RegexMatchTimeoutException e)
            {
                return false;
            }
            catch (ArgumentException e)
            {
                return false;
            }

            try
            {
                return Regex.IsMatch(email,
                    @"^[^@\s]+@[^@\s]+\.[^@\s]+$",
                    RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250));
            }
            catch (RegexMatchTimeoutException)
            {
                return false;
            }
        }
    }
}
Imports System.Globalization
Imports System.Text.RegularExpressions

Public Class RegexUtilities
    Public Shared Function IsValidEmail(email As String) As Boolean

        If String.IsNullOrWhiteSpace(email) Then Return False

        ' Use IdnMapping class to convert Unicode domain names.
        Try
            'Examines the domain part of the email and normalizes it.
            Dim DomainMapper =
                Function(match As Match) As String

                    'Use IdnMapping class to convert Unicode domain names.
                    Dim idn = New IdnMapping

                    'Pull out and process domain name (throws ArgumentException on invalid)
                    Dim domainName As String = idn.GetAscii(match.Groups(2).Value)

                    Return match.Groups(1).Value & domainName

                End Function

            'Normalize the domain
            email = Regex.Replace(email, "(@)(.+)$", DomainMapper,
                                  RegexOptions.None, TimeSpan.FromMilliseconds(200))

        Catch e As RegexMatchTimeoutException
            Return False

        Catch e As ArgumentException
            Return False

        End Try

        Try
            Return Regex.IsMatch(email,
                                 "^[^@\s]+@[^@\s]+\.[^@\s]+$",
                                 RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250))

        Catch e As RegexMatchTimeoutException
            Return False

        End Try

    End Function
End Class

En este ejemplo, el patrón de expresión regular ^[^@\s]+@[^@\s]+\.[^@\s]+$ se interpreta como se muestra en la tabla siguiente. La expresión regular se compila mediante la marca RegexOptions.IgnoreCase.

Patrón Descripción
^ Comenzar la búsqueda de coincidencia al principio de la cadena.
[^@\s]+ Buscar una o más repeticiones de cualquier carácter que no sea el carácter @ o el espacio en blanco.
@ Buscar el carácter @.
[^@\s]+ Buscar una o más repeticiones de cualquier carácter que no sea el carácter @ o el espacio en blanco.
\. Buscar un único carácter de punto.
[^@\s]+ Buscar una o más repeticiones de cualquier carácter que no sea el carácter @ o el espacio en blanco.
$ Finalizar la búsqueda al final de la cadena.

Importante

Esta expresión regular no se ha diseñado para cubrir todos los aspectos de una dirección de correo electrónico válida. Se proporciona como un ejemplo para ampliarla según sea necesario.

Vea también