Come verificare che le stringhe siano in formato di posta elettronica valido
L'esempio di questo articolo usa un'espressione regolare per verificare la validità del formato di posta elettronica di una stringa.
Questa espressione regolare è relativamente semplice rispetto a ciò che può essere effettivamente usato come messaggio di posta elettronica. L'uso di un'espressione regolare per convalidare un messaggio di posta elettronica è utile per assicurarsi che la struttura di un messaggio sia corretta. Tuttavia, non può sostituire la verifica dell'effettiva esistenza del messaggio.
✔️ Usare un'espressione regolare semplice per verificare la validità della struttura di un messaggio di posta elettronica.
✔️ Inviare un messaggio di posta elettronica di prova all'indirizzo fornito da un utente dell'app.
❌ NON usare un'espressione regolare come unico modo per convalidare un messaggio di posta elettronica.
Se per verificare che la struttura di un messaggio di posta elettronica sia corretta si tenta di creare l'espressione regolare perfetta, questa diventa talmente complessa da essere incredibilmente difficile da sottoporre a debug o migliorare. Le espressioni regolari non possono convalidare l'esistenza di un messaggio di posta elettronica, anche se è strutturato correttamente. Il modo migliore per convalidare un messaggio di posta elettronica consiste nell'inviare un messaggio di prova all'indirizzo.
Avviso
Quando si usa System.Text.RegularExpressions per elaborare l'input non attendibile, passare un timeout. Un utente malintenzionato può fornire input a RegularExpressions
, provocando un attacco Denial of Service. Le API del framework ASP.NET Core che usano RegularExpressions
passano un timeout.
Esempio
Nell'esempio viene definito un metodo IsValidEmail
che restituisce true
se la stringa contiene un indirizzo di posta elettronica valido e false
in caso contrario, ma non esegue alcuna altra azione.
Per verificare che l'indirizzo di posta elettronica sia valido, il metodo IsValidEmail
chiama il metodo Regex.Replace(String, String, MatchEvaluator) con il criterio di espressione regolare (@)(.+)$
per separare il nome di dominio dall'indirizzo di posta elettronica. Il terzo parametro è un delegato MatchEvaluator che rappresenta il metodo che elabora e sostituisce il testo corrispondente. Il criterio dell'espressione regolare viene interpretato nel modo seguente:
Modello | Descrizione |
---|---|
(@) |
Trova la corrispondenza con il carattere @. Questa parte è il primo gruppo di acquisizione. |
(.+) |
Trova la corrispondenza con una o più occorrenze di qualsiasi carattere. Questa parte è il secondo gruppo di acquisizione. |
$ |
Terminare la corrispondenza alla fine della stringa. |
Il nome di dominio, insieme al carattere @, viene passato al metodo DomainMapper
. Il metodo usa la classe IdnMapping per convertire i caratteri Unicode che si trovano all'esterno dell'intervallo di caratteri US-ASCII in Punycode. Il metodo imposta inoltre il flag invalid
su True
se il metodo IdnMapping.GetAscii rileva caratteri non validi nel nome di dominio. Il metodo restituisce il nome di dominio Punycode preceduto dal simbolo @ al metodo IsValidEmail
.
Suggerimento
È consigliabile usare il criterio di espressione regolare semplice (@)(.+)$
per normalizzare il dominio e quindi restituire un valore che indica se è passato o non riuscito. Tuttavia, l'esempio in questo articolo descrive come usare ulteriormente un'espressione regolare per convalidare il messaggio di posta elettronica. Indipendentemente dalla modalità di convalida di un messaggio di posta elettronica, è consigliabile inviare sempre un messaggio di prova all'indirizzo per assicurarsi che esista.
Il metodo IsValidEmail
chiama quindi il metodo Regex.IsMatch(String, String) per verificare che l'indirizzo sia conforme a un criterio di espressione regolare.
Il metodo IsValidEmail
determina semplicemente se il formato di posta elettronica è valido per un indirizzo, ma non convalida l'esistenza del messaggio. Inoltre, il metodo IsValidEmail
non verifica che il nome di dominio di primo livello sia un nome di dominio valido elencato nella pagina del Database delle aree radice sul sito IANA, cosa che richiederebbe un'operazione di ricerca.
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
In questo esempio il modello di espressione regolare ^[^@\s]+@[^@\s]+\.[^@\s]+$
viene interpretato come illustrato nella tabella seguente. L'espressione regolare viene compilata usando il flag RegexOptions.IgnoreCase.
Modello | Descrizione |
---|---|
^ |
Iniziare la ricerca della corrispondenza all'inizio della stringa. |
[^@\s]+ |
Trova una o più occorrenze di qualsiasi carattere diverso da @ o dallo spazio vuoto. |
@ |
Trova la corrispondenza con il carattere @. |
[^@\s]+ |
Trova una o più occorrenze di qualsiasi carattere diverso da @ o dallo spazio vuoto. |
\. |
Trova un singolo carattere punto. |
[^@\s]+ |
Trova una o più occorrenze di qualsiasi carattere diverso da @ o dallo spazio vuoto. |
$ |
Terminare la corrispondenza alla fine della stringa. |
Importante
Questa espressione regolare non è progettata per coprire ogni aspetto di un indirizzo di posta elettronica valido. Viene fornita come esempio da estendere in base alle esigenze.