¿Cómo analizar la dirección de correo electrónico formateada en nombre para mostrar y dirección de correo electrónico?

StackOverflow https://stackoverflow.com/questions/162681

  •  03-07-2019
  •  | 
  •  

Pregunta

Dada la dirección de correo electrónico: " Jim " < jim@example.com >

Si intento pasar esto a MailAddress obtengo la excepción:

  

La cadena especificada no tiene el formato requerido para una dirección de correo electrónico.

¿Cómo analizo esta dirección en un nombre para mostrar (Jim) y una dirección de correo electrónico (jim@example.com) en C #?

EDITAR: estoy buscando el código C # para analizarlo.

EDIT2: Descubrí que MailAddress estaba lanzando la excepción porque tenía un espacio al comienzo de la cadena de dirección de correo electrónico.

¿Fue útil?

Solución

Si está buscando analizar la dirección de correo electrónico manualmente, desea leer RFC2822 ( https://tools.ietf.org/html/rfc822.html#section-3.4 ). La sección 3.4 habla sobre el formato de dirección.

Pero analizar direcciones de correo electrónico correctamente no es fácil y MailAddress debería poder manejar la mayoría de los escenarios.

De acuerdo con la documentación de MSDN para "Tom Smith <tsmith@contoso.com>":

http://msdn.microsoft.com/en-us/library /591bk9e8.aspx

Debería poder analizar una dirección con un nombre para mostrar. Dan <=> como ejemplo. Tal vez las citas son el problema? Si es así, simplemente elimine las comillas y use MailAddress para analizar el resto.

string emailAddress = "\"Jim\" <jim@example.com>";

MailAddress address = new MailAddress(emailAddress.Replace("\"", ""));

Analizar manualmente RFC2822 no vale la pena si puede evitarlo.

Otros consejos

Funciona para mí:

string s = "\"Jim\" <jim@example.com>";
System.Net.Mail.MailAddress a = new System.Net.Mail.MailAddress(s);
Debug.WriteLine("DisplayName:  " +  a.DisplayName);
Debug.WriteLine("Address:  " + a.Address);

La clase MailAddress tiene un método privado que analiza una dirección de correo electrónico. No sé qué tan bueno es, pero tendería a usarlo en lugar de escribir el mío.

Prueba:

"Jimbo <jim@example.com>"

prueba: " Jim " < jim@example.com > no estoy seguro de si funcionará, pero así es como generalmente lo veo en los clientes de correo electrónico.

si asume que siempre hay un espacio entre los 2, podría usar String.Split ('') para dividirlo en los espacios. Eso le daría una matriz con las partes divididas.

así que tal vez así:

string str = "\"Jimbo\" jim@example.com"
string[] parts = str.Trim().Replace("\"","").Split(' ')

Un problema con esto para verificar es que si el nombre para mostrar tiene un espacio, se dividirá en 2 o más elementos en su matriz, pero el correo electrónico siempre será el último.

Editar: es posible que también necesite editar los corchetes, solo agregue reemplazos por esos.

Acabo de escribir esto, toma la primera dirección de correo electrónico bien formada de una cadena. De esa manera, no tiene que asumir dónde está la dirección de correo electrónico en la cadena

Mucho espacio para mejorar, pero necesito irme a trabajar :)

class Program
{
    static void Main(string[] args)
    {
        string email = "\"Jimbo\" <jim@example.com>";
        Console.WriteLine(parseEmail(email));
    }

    private static string parseEmail(string inputString)
    {
        Regex r = 
            new Regex(@"^((?:(?:(?:[a-zA-Z0-9][\.\-\+_]?)*)[a-zA-Z0-9])+)\@((?:(?:(?:[a-zA-Z0-9][\.\-_]?){0,62})[a-zA-Z0-9])+)\.([a-zA-Z0-9]{2,6})$");

        string[] tokens = inputString.Split(' ');

        foreach (string s in tokens)
        {
            string temp = s;
            temp = temp.TrimStart('<'); temp = temp.TrimEnd('>');

            if (r.Match(temp).Success)
                return temp;
        }

        throw new ArgumentException("Not an e-mail address");
    }
}

Es un poco " áspero y listo " pero funcionará para el ejemplo que has dado:

        string emailAddress, displayname;
        string unparsedText = "\"Jimbo\" <jim@example.com>";
        string[] emailParts = unparsedText.Split(new char[] { '<' });

        if (emailParts.Length == 2)
        {
            displayname = emailParts[0].Trim(new char[] { ' ', '\"' });
            emailAddress = emailParts[1].TrimEnd('>');
        }
new MailAddress("jim@example.com", "Jimbo");

para analizar la cadena que proporcionó:

string input = "\"Jimbo\" jim@example.com";
string[] pieces = input.Split(' ');
MailAddress ma = new MailAddress(pieces[1].Replace("<", string.Empty).Replace(">",string.Empty), pieces[0].Replace("\"", string.Empty));
string inputEmailString = "\"Jimbo\" <jim@example.com>";
string[] strSet =  inputEmailString.Split('\"','<','>');   

MailAddress mAddress = new MailAddress(strSet[0], strSet[2]);

Para manejar espacios incrustados, divídalos entre paréntesis, de la siguiente manera:

string addrin = "\"Jim Smith\" <jim@example.com>";
char[] bracks = {'<','>'};
string[] pieces = addrin.Split(bracks);
pieces[0] = pieces[0]
  .Substring(0, pieces[0].Length - 1)
  .Replace("\"", string.Empty);
MailAddress ma = new MailAddress(pieces[1], pieces[0]);

Entonces, esto es lo que he hecho. Es un poco rápido y sucio, pero parece funcionar.

string emailTo = "\"Jim\" <jim@example.com>";
string emailRegex = @"(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|""(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*"")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])";
string emailAddress = Regex.Match(emailTo.ToLower(), emailRegex).Value;
string displayName = null;

try
{
    displayName = emailTo.Substring(0, emailTo.ToLower().IndexOf(emailAddress) - 1);
}
catch 
{
    // No display name 
}

MailAddress addr = new MailAddress(emailAddress, displayName);

¿Comentarios?

No codifico en este idioma, pero veo dos problemas que es posible que desee verificar:

1- No sabes exactamente por qué fue rechazado. Una posibilidad inmediata era que tuviera una lista negra para example.com.

2- La solución real que desea es probablemente implementar un validador estricto. Stack Overflow es probablemente un buen lugar para desarrollar esto, porque hay muchas personas con experiencia práctica.

Aquí hay un par de cosas que necesita:

  1. recortar espacios en blanco y obviamente crujidos.
  2. analizar en partes individuales (nombre para mostrar, lado izquierdo de la dirección, lado derecho de la dirección).
  3. valide cada uno de estos con un validador específico de estructura de datos. Por ejemplo, el lado derecho debe ser un FQDN válido (o un nombre de host no calificado si está en un sistema de correo liberal).

Ese es el mejor enfoque a largo plazo para resolver este problema.

Puedo sugerir mi solución basada en expresiones regulares para decodificar valores de campo de dirección de correo electrónico (" From " ;, " To ") y el valor de campo " Asunto & Quot;

https: // www .codeproject.com / Tips / 1198601 / Parsing-and-Decoding-Values-of-Some-Email-Message

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top