Como analisar endereço de e-mail formatado em nome de exibição e endereço de e-mail?
-
03-07-2019 - |
Pergunta
Dado o endereço de e-mail: "Jim"
Se eu tentar passar isso para MailAddress eu recebo a exceção:
A cadeia especificada não está na forma requerida para um endereço de e-mail.
Como faço para analisar este endereço em um nome de exibição (Jim) e endereço de e-mail (jim@example.com) em C #?
EDIT:. Eu estou procurando código C # para analisá-lo
EDIT2: Descobri que a exceção foi sendo jogado por MailAddress porque eu tinha um espaço no início da cadeia de endereço de e-mail.
Solução
Se você estiver olhando para analisar o endereço de e-mail manualmente, você quer ler RFC2822 ( https://tools.ietf.org/html/rfc822.html#section-3.4 ). Seção 3.4 fala sobre o formato de endereço.
Mas a análise de endereços de e-mail está corretamente não é fácil e MailAddress
deve ser capaz de lidar com a maioria dos cenários.
De acordo com a documentação do MSDN para MailAddress
:
http://msdn.microsoft.com/en-us/library /591bk9e8.aspx
Deve ser capaz de analisar um endereço com um nome de exibição. Eles dão "Tom Smith <tsmith@contoso.com>"
como um exemplo. Talvez as citações são o problema? Nesse caso, basta tirar as aspas e usar MailAddress para analisar o resto.
string emailAddress = "\"Jim\" <jim@example.com>";
MailAddress address = new MailAddress(emailAddress.Replace("\"", ""));
manualmente análise RFC2822 não vale a pena se você pode evitá-lo.
Outras dicas
funciona para mim:
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);
A classe MailAddress tem um método particular que analisa um endereço de e-mail. Não sei como é bom, mas eu tendem a usá-lo em vez de escrever meu próprio.
Tente:
"Jimbo <jim@example.com>"
tentar: "Jim"
Se você fazer a suposição de que há sempre um espaço entre a 2, você pode simplesmente usar String.Split (' ') para dividi-lo sobre os espaços. Que lhe daria uma matriz com a divisão de peças.
então talvez assim:
string str = "\"Jimbo\" jim@example.com"
string[] parts = str.Trim().Replace("\"","").Split(' ')
Um problema com esta a verificar é que, se o nome de exibição tem um espaço nele, será dividida em 2 ou mais itens em sua própria matriz, mas o e-mail seria sempre passado.
Edit - você também pode precisar de editar os suportes, basta adicionar substitui com aqueles.
Eu escrevi isso, ele pega o endereço de e-mail primeiro poço formado a partir de uma string. Dessa forma, você não tem que assumir que o endereço de e-mail está na cadeia
Muito espaço para melhoria, mas eu preciso sair para o trabalho:)
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");
}
}
É um "áspero e pronto" pouco, mas vai trabalhar para o exemplo que você deu:
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 analisar a cadeia que deu:
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 lidar com espaços incorporados, divididos nos suportes, da seguinte forma:
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]);
Então, isso é o que tenho feito. É um pouco rápido e sujo, mas 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);
Comentários?
Eu não código nesta língua, mas eu vejo duas questões que você pode querer verificar:
1- Você não sabe exatamente por que ela foi rejeitada. Na possibilidade imediata foi que tem uma lista negra para example.com.
2 A solução real que você quer é implementar provavelmente um validador rigoroso. Stack Overflow é provavelmente um bom lugar para desenvolver isso, porque há muitas pessoas com experiência prática.
Aqui estão algumas coisas que você precisa:
- espaço em branco da guarnição e, obviamente, cruft.
- parse em partes individuais (nome de exibição,-mão-lado esquerdo do endereço, do lado direito de endereço).
- validar cada uma delas com um validador específica estrutura de dados. Por exemplo, as necessidades do lado direito de ser um FQDN válido (ou o nome não qualificado se você estiver em um sistema de correio liberal).
Essa é a abordagem melhor a longo prazo para resolver este problema.
Posso sugerir a minha solução baseada em regex para decodificar os valores de campo de endereço de e-mail ( "From", "To") e valor do campo "Assunto"