Які хороші бібліотеки перевірки електронної адреси для Java? Чи існують альтернативи для спільноти валідатора ?
Які хороші бібліотеки перевірки електронної адреси для Java? Чи існують альтернативи для спільноти валідатора ?
Відповіді:
Apache Commons загалом відомий як надійний проект. Майте на увазі, однак, вам все одно доведеться надіслати електронний лист для підтвердження, якщо ви хочете переконатися, що це справжній електронний лист, і що власник хоче, щоб його використовували на вашому веб-сайті.
EDIT : Була помилка, в якій вона надто обмежувала домен, через що вона не приймала дійсні електронні листи з нових TLD.
Ця помилка була вирішена 03 / січня / 15 02:48 у commons-validator версії 1.4.1
EmailValidator
клас Apache не надсилає електронне повідомлення для підтвердження.
Використовувати офіційний пакет електронної пошти Java - це найпростіше:
public static boolean isValidEmailAddress(String email) {
boolean result = true;
try {
InternetAddress emailAddr = new InternetAddress(email);
emailAddr.validate();
} catch (AddressException ex) {
result = false;
}
return result;
}
.
, .com
, com.
, abc
і 123
. Крім того, додавання пробілу чи пробілу білого простору також не приводить до недійсності рядків. Ти будеш суддею!
Валідатор Apache Commons може використовуватися як зазначено в інших відповідях.
pom.xml:
<dependency>
<groupId>commons-validator</groupId>
<artifactId>commons-validator</artifactId>
<version>1.4.1</version>
</dependency>
build.gradle:
compile 'commons-validator:commons-validator:1.4.1'
Імпорт:
import org.apache.commons.validator.routines.EmailValidator;
Код:
String email = "myName@example.com";
boolean valid = EmailValidator.getInstance().isValid(email);
і дозволити місцеві адреси
boolean allowLocal = true;
boolean valid = EmailValidator.getInstance(allowLocal).isValid(email);
Пізня відповідь, але я вважаю, що це просто і гідно:
public boolean isValidEmailAddress(String email) {
String ePattern = "^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$";
java.util.regex.Pattern p = java.util.regex.Pattern.compile(ePattern);
java.util.regex.Matcher m = p.matcher(email);
return m.matches();
}
Випробування :
Для виробничих цілей перевірку доменних імен слід виконувати в мережі.
Якщо ви намагаєтеся перевірити форму, отриману від клієнта, або просто перевірку бобових - нехай це буде просто. Краще робити вільну перевірку електронної пошти, а не робити сувору та відхиляти деяких людей (наприклад, коли вони намагаються зареєструватися для вашого веб-сервісу). Оскільки майже все, що дозволено в частині електронної пошти електронної пошти та стільки нових доменів додаються буквально щомісяця (наприклад, .company, .entreprise, .estate), безпечніше не бути обмежувальним:
Pattern pattern = Pattern.compile("^.+@.+\\..+$");
Matcher matcher = pattern.matcher(email);
Пізно до запитання, ось, але: я підтримую клас за цією адресою: http://lacinato.com/cm/software/emailrelated/emailaddress
Він заснований на класі Les Hazlewood, але має численні вдосконалення та виправляє кілька помилок. Ліцензія Apache.
Я вважаю, що це найдієвіший аналізатор електронної пошти на Яві, і я ще не бачив ще одного здатного на будь-якій мові, хоча там може бути і один. Це не аналізатор у стилі лексера, але він використовує складний Java-регекс, і, таким чином, не настільки ефективний, як міг би бути, але моя компанія розібрала з ним понад 10 мільярдів реальних адрес: це, безумовно, корисно з високою продуктивністю ситуація. Можливо, раз на рік він потраплятиме на адресу, яка спричиняє переповнення стека регулярних виразів (відповідним чином), але це спам-адреси, довжиною яких є сотні чи тисячі символів, з багатьма цитатами та дужками тощо.
RFC 2822 та пов’язані з цим специфікації справді досить дозвільні з точки зору адрес електронної пошти, тому клас на кшталт цього є надмірним для більшості застосувань. Наприклад, наведена нижче законна адреса відповідно до специфікації, пробілів і всіх:
"<bob \" (here) " < (hi there) "bob(the man)smith" (hi) @ (there) example.com (hello) > (again)
Жоден поштовий сервер не дозволив би цього, але цей клас може проаналізувати його (і переписати його у придатну форму).
Ми виявили існуючі параметри розбору електронної пошти Java недостатньо міцними (це означає, що всі вони не могли проаналізувати деякі дійсні адреси), тому ми створили цей клас.
Код добре задокументований і має безліч простих змін, щоб дозволити або заборонити певні форми електронної пошти. Він також пропонує безліч методів доступу до певних частин адреси (ліворуч, праворуч, особистих імен, коментарів тощо), для розбору / перевірки заголовків списку поштових скриньок, для аналізу / перевірки повернення шляху (що є унікальним серед заголовків) тощо.
Код, як написано, має javamail залежність, але його легко видалити, якщо ви не хочете незначної функціональності, яку він надає.
Мені просто цікаво, чому ніхто не придумав @Email
додаткових обмежень сплячого валідатора. Сам валідатор є EmailValidator
.
Les Hazlewood написав дуже ретельний RFC 2822 сумісний клас валідатора електронної пошти, використовуючи регулярні вирази Java. Ви можете знайти його за адресою http://www.leshazlewood.com/?p=23 . Однак його ретельність (або реалізація Java RE) призводить до неефективності - читайте коментарі про час розбору довгих адрес.
Я переніс частину коду в Zend_Validator_Email:
@FacesValidator("emailValidator")
public class EmailAddressValidator implements Validator {
private String localPart;
private String hostName;
private boolean domain = true;
Locale locale;
ResourceBundle bundle;
private List<FacesMessage> messages = new ArrayList<FacesMessage>();
private HostnameValidator hostnameValidator;
@Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
setOptions(component);
String email = (String) value;
boolean result = true;
Pattern pattern = Pattern.compile("^(.+)@([^@]+[^.])$");
Matcher matcher = pattern.matcher(email);
locale = context.getViewRoot().getLocale();
bundle = ResourceBundle.getBundle("com.myapp.resources.validationMessages", locale);
boolean length = true;
boolean local = true;
if (matcher.find()) {
localPart = matcher.group(1);
hostName = matcher.group(2);
if (localPart.length() > 64 || hostName.length() > 255) {
length = false;
addMessage("enterValidEmail", "email.AddressLengthExceeded");
}
if (domain == true) {
hostnameValidator = new HostnameValidator();
hostnameValidator.validate(context, component, hostName);
}
local = validateLocalPart();
if (local && length) {
result = true;
} else {
result = false;
}
} else {
result = false;
addMessage("enterValidEmail", "invalidEmailAddress");
}
if (result == false) {
throw new ValidatorException(messages);
}
}
private boolean validateLocalPart() {
// First try to match the local part on the common dot-atom format
boolean result = false;
// Dot-atom characters are: 1*atext *("." 1*atext)
// atext: ALPHA / DIGIT / and "!", "#", "$", "%", "&", "'", "*",
// "+", "-", "/", "=", "?", "^", "_", "`", "{", "|", "}", "~"
String atext = "a-zA-Z0-9\\u0021\\u0023\\u0024\\u0025\\u0026\\u0027\\u002a"
+ "\\u002b\\u002d\\u002f\\u003d\\u003f\\u005e\\u005f\\u0060\\u007b"
+ "\\u007c\\u007d\\u007e";
Pattern regex = Pattern.compile("^["+atext+"]+(\\u002e+["+atext+"]+)*$");
Matcher matcher = regex.matcher(localPart);
if (matcher.find()) {
result = true;
} else {
// Try quoted string format
// Quoted-string characters are: DQUOTE *([FWS] qtext/quoted-pair) [FWS] DQUOTE
// qtext: Non white space controls, and the rest of the US-ASCII characters not
// including "\" or the quote character
String noWsCtl = "\\u0001-\\u0008\\u000b\\u000c\\u000e-\\u001f\\u007f";
String qText = noWsCtl + "\\u0021\\u0023-\\u005b\\u005d-\\u007e";
String ws = "\\u0020\\u0009";
regex = Pattern.compile("^\\u0022(["+ws+qText+"])*["+ws+"]?\\u0022$");
matcher = regex.matcher(localPart);
if (matcher.find()) {
result = true;
} else {
addMessage("enterValidEmail", "email.AddressDotAtom");
addMessage("enterValidEmail", "email.AddressQuotedString");
addMessage("enterValidEmail", "email.AddressInvalidLocalPart");
}
}
return result;
}
private void addMessage(String detail, String summary) {
String detailMsg = bundle.getString(detail);
String summaryMsg = bundle.getString(summary);
messages.add(new FacesMessage(FacesMessage.SEVERITY_ERROR, summaryMsg, detailMsg));
}
private void setOptions(UIComponent component) {
Boolean domainOption = Boolean.valueOf((String) component.getAttributes().get("domain"));
//domain = (domainOption == null) ? true : domainOption.booleanValue();
}
}
З валідатором імені хоста, як описано нижче:
@FacesValidator("hostNameValidator")
public class HostnameValidator implements Validator {
private Locale locale;
private ResourceBundle bundle;
private List<FacesMessage> messages;
private boolean checkTld = true;
private boolean allowLocal = false;
private boolean allowDNS = true;
private String tld;
private String[] validTlds = {"ac", "ad", "ae", "aero", "af", "ag", "ai",
"al", "am", "an", "ao", "aq", "ar", "arpa", "as", "asia", "at", "au",
"aw", "ax", "az", "ba", "bb", "bd", "be", "bf", "bg", "bh", "bi", "biz",
"bj", "bm", "bn", "bo", "br", "bs", "bt", "bv", "bw", "by", "bz", "ca",
"cat", "cc", "cd", "cf", "cg", "ch", "ci", "ck", "cl", "cm", "cn", "co",
"com", "coop", "cr", "cu", "cv", "cx", "cy", "cz", "de", "dj", "dk",
"dm", "do", "dz", "ec", "edu", "ee", "eg", "er", "es", "et", "eu", "fi",
"fj", "fk", "fm", "fo", "fr", "ga", "gb", "gd", "ge", "gf", "gg", "gh",
"gi", "gl", "gm", "gn", "gov", "gp", "gq", "gr", "gs", "gt", "gu", "gw",
"gy", "hk", "hm", "hn", "hr", "ht", "hu", "id", "ie", "il", "im", "in",
"info", "int", "io", "iq", "ir", "is", "it", "je", "jm", "jo", "jobs",
"jp", "ke", "kg", "kh", "ki", "km", "kn", "kp", "kr", "kw", "ky", "kz",
"la", "lb", "lc", "li", "lk", "lr", "ls", "lt", "lu", "lv", "ly", "ma",
"mc", "md", "me", "mg", "mh", "mil", "mk", "ml", "mm", "mn", "mo",
"mobi", "mp", "mq", "mr", "ms", "mt", "mu", "museum", "mv", "mw", "mx",
"my", "mz", "na", "name", "nc", "ne", "net", "nf", "ng", "ni", "nl",
"no", "np", "nr", "nu", "nz", "om", "org", "pa", "pe", "pf", "pg", "ph",
"pk", "pl", "pm", "pn", "pr", "pro", "ps", "pt", "pw", "py", "qa", "re",
"ro", "rs", "ru", "rw", "sa", "sb", "sc", "sd", "se", "sg", "sh", "si",
"sj", "sk", "sl", "sm", "sn", "so", "sr", "st", "su", "sv", "sy", "sz",
"tc", "td", "tel", "tf", "tg", "th", "tj", "tk", "tl", "tm", "tn", "to",
"tp", "tr", "travel", "tt", "tv", "tw", "tz", "ua", "ug", "uk", "um",
"us", "uy", "uz", "va", "vc", "ve", "vg", "vi", "vn", "vu", "wf", "ws",
"ye", "yt", "yu", "za", "zm", "zw"};
private Map<String, Map<Integer, Integer>> idnLength;
private void init() {
Map<Integer, Integer> biz = new HashMap<Integer, Integer>();
biz.put(5, 17);
biz.put(11, 15);
biz.put(12, 20);
Map<Integer, Integer> cn = new HashMap<Integer, Integer>();
cn.put(1, 20);
Map<Integer, Integer> com = new HashMap<Integer, Integer>();
com.put(3, 17);
com.put(5, 20);
Map<Integer, Integer> hk = new HashMap<Integer, Integer>();
hk.put(1, 15);
Map<Integer, Integer> info = new HashMap<Integer, Integer>();
info.put(4, 17);
Map<Integer, Integer> kr = new HashMap<Integer, Integer>();
kr.put(1, 17);
Map<Integer, Integer> net = new HashMap<Integer, Integer>();
net.put(3, 17);
net.put(5, 20);
Map<Integer, Integer> org = new HashMap<Integer, Integer>();
org.put(6, 17);
Map<Integer, Integer> tw = new HashMap<Integer, Integer>();
tw.put(1, 20);
Map<Integer, Integer> idn1 = new HashMap<Integer, Integer>();
idn1.put(1, 20);
Map<Integer, Integer> idn2 = new HashMap<Integer, Integer>();
idn2.put(1, 20);
Map<Integer, Integer> idn3 = new HashMap<Integer, Integer>();
idn3.put(1, 20);
Map<Integer, Integer> idn4 = new HashMap<Integer, Integer>();
idn4.put(1, 20);
idnLength = new HashMap<String, Map<Integer, Integer>>();
idnLength.put("BIZ", biz);
idnLength.put("CN", cn);
idnLength.put("COM", com);
idnLength.put("HK", hk);
idnLength.put("INFO", info);
idnLength.put("KR", kr);
idnLength.put("NET", net);
idnLength.put("ORG", org);
idnLength.put("TW", tw);
idnLength.put("ایران", idn1);
idnLength.put("中国", idn2);
idnLength.put("公司", idn3);
idnLength.put("网络", idn4);
messages = new ArrayList<FacesMessage>();
}
public HostnameValidator() {
init();
}
@Override
public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
String hostName = (String) value;
locale = context.getViewRoot().getLocale();
bundle = ResourceBundle.getBundle("com.myapp.resources.validationMessages", locale);
Pattern ipPattern = Pattern.compile("^[0-9a-f:\\.]*$", Pattern.CASE_INSENSITIVE);
Matcher ipMatcher = ipPattern.matcher(hostName);
if (ipMatcher.find()) {
addMessage("hostname.IpAddressNotAllowed");
throw new ValidatorException(messages);
}
boolean result = false;
// removes last dot (.) from hostname
hostName = hostName.replaceAll("(\\.)+$", "");
String[] domainParts = hostName.split("\\.");
boolean status = false;
// Check input against DNS hostname schema
if ((domainParts.length > 1) && (hostName.length() > 4) && (hostName.length() < 255)) {
status = false;
dowhile:
do {
// First check TLD
int lastIndex = domainParts.length - 1;
String domainEnding = domainParts[lastIndex];
Pattern tldRegex = Pattern.compile("([^.]{2,10})", Pattern.CASE_INSENSITIVE);
Matcher tldMatcher = tldRegex.matcher(domainEnding);
if (tldMatcher.find() || domainEnding.equals("ایران")
|| domainEnding.equals("中国")
|| domainEnding.equals("公司")
|| domainEnding.equals("网络")) {
// Hostname characters are: *(label dot)(label dot label); max 254 chars
// label: id-prefix [*ldh{61} id-prefix]; max 63 chars
// id-prefix: alpha / digit
// ldh: alpha / digit / dash
// Match TLD against known list
tld = (String) tldMatcher.group(1).toLowerCase().trim();
if (checkTld == true) {
boolean foundTld = false;
for (int i = 0; i < validTlds.length; i++) {
if (tld.equals(validTlds[i])) {
foundTld = true;
}
}
if (foundTld == false) {
status = false;
addMessage("hostname.UnknownTld");
break dowhile;
}
}
/**
* Match against IDN hostnames
* Note: Keep label regex short to avoid issues with long patterns when matching IDN hostnames
*/
List<String> regexChars = getIdnRegexChars();
// Check each hostname part
int check = 0;
for (String domainPart : domainParts) {
// Decode Punycode domainnames to IDN
if (domainPart.indexOf("xn--") == 0) {
domainPart = decodePunycode(domainPart.substring(4));
}
// Check dash (-) does not start, end or appear in 3rd and 4th positions
if (domainPart.indexOf("-") == 0
|| (domainPart.length() > 2 && domainPart.indexOf("-", 2) == 2 && domainPart.indexOf("-", 3) == 3)
|| (domainPart.indexOf("-") == (domainPart.length() - 1))) {
status = false;
addMessage("hostname.DashCharacter");
break dowhile;
}
// Check each domain part
boolean checked = false;
for (int key = 0; key < regexChars.size(); key++) {
String regexChar = regexChars.get(key);
Pattern regex = Pattern.compile(regexChar);
Matcher regexMatcher = regex.matcher(domainPart);
status = regexMatcher.find();
if (status) {
int length = 63;
if (idnLength.containsKey(tld.toUpperCase())
&& idnLength.get(tld.toUpperCase()).containsKey(key)) {
length = idnLength.get(tld.toUpperCase()).get(key);
}
int utf8Length;
try {
utf8Length = domainPart.getBytes("UTF8").length;
if (utf8Length > length) {
addMessage("hostname.InvalidHostname");
} else {
checked = true;
break;
}
} catch (UnsupportedEncodingException ex) {
Logger.getLogger(HostnameValidator.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
if (checked) {
++check;
}
}
// If one of the labels doesn't match, the hostname is invalid
if (check != domainParts.length) {
status = false;
addMessage("hostname.InvalidHostnameSchema");
}
} else {
// Hostname not long enough
status = false;
addMessage("hostname.UndecipherableTld");
}
} while (false);
if (status == true && allowDNS) {
result = true;
}
} else if (allowDNS == true) {
addMessage("hostname.InvalidHostname");
throw new ValidatorException(messages);
}
// Check input against local network name schema;
Pattern regexLocal = Pattern.compile("^(([a-zA-Z0-9\\x2d]{1,63}\\x2e)*[a-zA-Z0-9\\x2d]{1,63}){1,254}$", Pattern.CASE_INSENSITIVE);
boolean checkLocal = regexLocal.matcher(hostName).find();
if (allowLocal && !status) {
if (checkLocal) {
result = true;
} else {
// If the input does not pass as a local network name, add a message
result = false;
addMessage("hostname.InvalidLocalName");
}
}
// If local network names are not allowed, add a message
if (checkLocal && !allowLocal && !status) {
result = false;
addMessage("hostname.LocalNameNotAllowed");
}
if (result == false) {
throw new ValidatorException(messages);
}
}
private void addMessage(String msg) {
String bundlMsg = bundle.getString(msg);
messages.add(new FacesMessage(FacesMessage.SEVERITY_ERROR, bundlMsg, bundlMsg));
}
/**
* Returns a list of regex patterns for the matched TLD
* @param tld
* @return
*/
private List<String> getIdnRegexChars() {
List<String> regexChars = new ArrayList<String>();
regexChars.add("^[a-z0-9\\x2d]{1,63}$");
Document doc = null;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
try {
InputStream validIdns = getClass().getClassLoader().getResourceAsStream("com/myapp/resources/validIDNs_1.xml");
DocumentBuilder builder = factory.newDocumentBuilder();
doc = builder.parse(validIdns);
doc.getDocumentElement().normalize();
} catch (SAXException ex) {
Logger.getLogger(HostnameValidator.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(HostnameValidator.class.getName()).log(Level.SEVERE, null, ex);
} catch (ParserConfigurationException ex) {
Logger.getLogger(HostnameValidator.class.getName()).log(Level.SEVERE, null, ex);
}
// prepare XPath
XPath xpath = XPathFactory.newInstance().newXPath();
NodeList nodes = null;
String xpathRoute = "//idn[tld=\'" + tld.toUpperCase() + "\']/pattern/text()";
try {
XPathExpression expr;
expr = xpath.compile(xpathRoute);
Object res = expr.evaluate(doc, XPathConstants.NODESET);
nodes = (NodeList) res;
} catch (XPathExpressionException ex) {
Logger.getLogger(HostnameValidator.class.getName()).log(Level.SEVERE, null, ex);
}
for (int i = 0; i < nodes.getLength(); i++) {
regexChars.add(nodes.item(i).getNodeValue());
}
return regexChars;
}
/**
* Decode Punycode string
* @param encoded
* @return
*/
private String decodePunycode(String encoded) {
Pattern regex = Pattern.compile("([^a-z0-9\\x2d]{1,10})", Pattern.CASE_INSENSITIVE);
Matcher matcher = regex.matcher(encoded);
boolean found = matcher.find();
if (encoded.isEmpty() || found) {
// no punycode encoded string, return as is
addMessage("hostname.CannotDecodePunycode");
throw new ValidatorException(messages);
}
int separator = encoded.lastIndexOf("-");
List<Integer> decoded = new ArrayList<Integer>();
if (separator > 0) {
for (int x = 0; x < separator; ++x) {
decoded.add((int) encoded.charAt(x));
}
} else {
addMessage("hostname.CannotDecodePunycode");
throw new ValidatorException(messages);
}
int lengthd = decoded.size();
int lengthe = encoded.length();
// decoding
boolean init = true;
int base = 72;
int index = 0;
int ch = 0x80;
int indexeStart = (separator == 1) ? (separator + 1) : 0;
for (int indexe = indexeStart; indexe < lengthe; ++lengthd) {
int oldIndex = index;
int pos = 1;
for (int key = 36; true; key += 36) {
int hex = (int) encoded.charAt(indexe++);
int digit = (hex - 48 < 10) ? hex - 22
: ((hex - 65 < 26) ? hex - 65
: ((hex - 97 < 26) ? hex - 97
: 36));
index += digit * pos;
int tag = (key <= base) ? 1 : ((key >= base + 26) ? 26 : (key - base));
if (digit < tag) {
break;
}
pos = (int) (pos * (36 - tag));
}
int delta = (int) (init ? ((index - oldIndex) / 700) : ((index - oldIndex) / 2));
delta += (int) (delta / (lengthd + 1));
int key;
for (key = 0; delta > 910; key += 36) {
delta = (int) (delta / 35);
}
base = (int) (key + 36 * delta / (delta + 38));
init = false;
ch += (int) (index / (lengthd + 1));
index %= (lengthd + 1);
if (lengthd > 0) {
for (int i = lengthd; i > index; i--) {
decoded.set(i, decoded.get(i - 1));
}
}
decoded.set(index++, ch);
}
// convert decoded ucs4 to utf8 string
StringBuilder sb = new StringBuilder();
for (int i = 0; i < decoded.size(); i++) {
int value = decoded.get(i);
if (value < 128) {
sb.append((char) value);
} else if (value < (1 << 11)) {
sb.append((char) (192 + (value >> 6)));
sb.append((char) (128 + (value & 63)));
} else if (value < (1 << 16)) {
sb.append((char) (224 + (value >> 12)));
sb.append((char) (128 + ((value >> 6) & 63)));
sb.append((char) (128 + (value & 63)));
} else if (value < (1 << 21)) {
sb.append((char) (240 + (value >> 18)));
sb.append((char) (128 + ((value >> 12) & 63)));
sb.append((char) (128 + ((value >> 6) & 63)));
sb.append((char) (128 + (value & 63)));
} else {
addMessage("hostname.CannotDecodePunycode");
throw new ValidatorException(messages);
}
}
return sb.toString();
}
/**
* Eliminates empty values from input array
* @param data
* @return
*/
private String[] verifyArray(String[] data) {
List<String> result = new ArrayList<String>();
for (String s : data) {
if (!s.equals("")) {
result.add(s);
}
}
return result.toArray(new String[result.size()]);
}
}
І validIDNs.xml з шаблонами регулярних виразів для різних tlds (занадто великий, щоб включати :)
<idnlist>
<idn>
<tld>AC</tld>
<pattern>^[\u002d0-9a-zà-öø-ÿāăąćĉċčďđēėęěĝġģĥħīįĵķĺļľŀłńņňŋőœŕŗřśŝşšţťŧūŭůűųŵŷźżž]{1,63}$</pattern>
</idn>
<idn>
<tld>AR</tld>
<pattern>^[\u002d0-9a-zà-ãç-êìíñ-õü]{1,63}$</pattern>
</idn>
<idn>
<tld>AS</tld>
<pattern>/^[\u002d0-9a-zà-öø-ÿāăąćĉċčďđēĕėęěĝğġģĥħĩīĭįıĵķĸĺļľłńņňŋōŏőœŕŗřśŝşšţťŧũūŭůűųŵŷźż]{1,63}$</pattern>
</idn>
<idn>
<tld>AT</tld>
<pattern>/^[\u002d0-9a-zà-öø-ÿœšž]{1,63}$</pattern>
</idn>
<idn>
<tld>BIZ</tld>
<pattern>^[\u002d0-9a-zäåæéöøü]{1,63}$</pattern>
<pattern>^[\u002d0-9a-záéíñóúü]{1,63}$</pattern>
<pattern>^[\u002d0-9a-záéíóöúüőű]{1,63}$</pattern>
</id>
</idlist>
public class Validations {
private Pattern regexPattern;
private Matcher regMatcher;
public String validateEmailAddress(String emailAddress) {
regexPattern = Pattern.compile("^[(a-zA-Z-0-9-\\_\\+\\.)]+@[(a-z-A-z)]+\\.[(a-zA-z)]{2,3}$");
regMatcher = regexPattern.matcher(emailAddress);
if(regMatcher.matches()) {
return "Valid Email Address";
} else {
return "Invalid Email Address";
}
}
public String validateMobileNumber(String mobileNumber) {
regexPattern = Pattern.compile("^\\+[0-9]{2,3}+-[0-9]{10}$");
regMatcher = regexPattern.matcher(mobileNumber);
if(regMatcher.matches()) {
return "Valid Mobile Number";
} else {
return "Invalid Mobile Number";
}
}
public static void main(String[] args) {
String emailAddress = "suryaprakash.pisay@gmail.com";
String mobileNumber = "+91-9986571622";
Validations validations = new Validations();
System.out.println(validations.validateEmailAddress(emailAddress));
System.out.println(validations.validateMobileNumber(mobileNumber));
}
}
Якщо ви хочете перевірити, чи правдива адреса електронної пошти, то VRFY отримає вам частину шляху. Я виявив, що це корисно для перевірки адрес інтрамережі (тобто електронних адрес для внутрішніх сайтів). Однак це менш корисно для поштових серверів Інтернету (див. Застереження у верхній частині цієї сторінки)
Хоча існує багато альтернатив спільноті Apache, їх реалізація в кращому випадку є рудиментарною (як і сама реалізація Apache commons ), а в інших випадках - навіть неправильною.
Я б також не тримався осторонь так званого простого "не обмежуючого" виразу; такого немає. Наприклад, @ дозволено кілька разів залежно від контексту, як ти знаєш, що потрібна? Простий регулярний вираз не зрозуміє цього, хоча електронна пошта має бути дійсною. Все, що складніше, стає схильним до помилок або навіть містить приховані вбивці продуктивності . Як ви збираєтеся підтримувати що - щось на зразок цього ?
Єдиний всебічний валідатор, сумісний з RFC, про який я знаю, - це валідатор електронної пошти-rfc2822 з його «доопрацьованим» регулярним виразом, відповідним чином названим Dragons.java . Він підтримує лише старі специфікації RFC-2822, хоча, хоча й достатньо підходить для сучасних потреб (RFC-5322 оновлює його у районах, які вже не входять у сферу щоденного використання).
Але дійсно те, що ви хочете, - це лексер, який правильно розбирає рядок і розбиває його на структуру компонентів відповідно до граматики RFC. З цього приводу EmailValidator4J здається багатообіцяючим, але він все ще молодий і обмежений.
Інший варіант - використання веб-сервісу, такого як перевірена в бою веб- служба перевірки Mailgun або API поштової скриньки (тільки що взяли перші результати Google). Він не суворо сумісний з RFC, але працює досить добре для сучасних потреб.
Що ви хочете перевірити? Адреса електронної пошти?
Адресу електронної пошти можна перевірити лише на відповідність її формату. Дивіться стандарт: RFC2822 . Найкращий спосіб зробити це регулярний вираз. Ви ніколи не дізнаєтесь, чи дійсно існує, не надсилаючи електронний лист.
Я перевірив загальнодоступний валідатор. Він містить клас org.apache.commons.validator.EmailValidator. Це здається гарною відправною точкою.
Поточна версія валідатора Apache Commons - це 1.3.1 .
Клас, який підтверджує, - org.apache.commons.validator.EmailValidator. Він має імпорт для org.apache.oro.text.perl.Perl5Util, який є відставним проектом ORO в Джакарті .
До речі, я виявив, що є версія 1.4, ось документи API . На сайті написано: "Остання публікація: 05 березня 2008 | Версія: 1.4-SNAPSHOT", але це не остаточно. Єдиний спосіб створити себе (але це знімок, а не звільнення) та використовувати або завантажувати звідси . Це означає, що 1,4 не було остаточним протягом трьох років (2008–2011). Це не в стилі Apache. Я шукаю кращого варіанту, але не знайшов такого, який би дуже прийнятий. Я хочу використовувати те, що добре перевірено, не хочу потрапляти на помилки.
Ви також можете перевірити довжину - електронні листи мають довжину не більше 254 символів. Я використовую валідатор apache commons, і він не перевіряє це.
Здається, немає ідеальних бібліотек або способів зробити це самостійно, якщо тільки вам не доведеться вчасно надсилати електронну пошту на електронну адресу і чекати відповіді (однак це може бути не можливим варіантом). Я в кінцевому підсумку скористався пропозицією звідси http://blog.logichigh.com/2010/09/02/validating-an-e-mail-address/ і відкоригував код, щоб він працював на Java.
public static boolean isValidEmailAddress(String email) {
boolean stricterFilter = true;
String stricterFilterString = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
String laxString = ".+@.+\\.[A-Za-z]{2}[A-Za-z]*";
String emailRegex = stricterFilter ? stricterFilterString : laxString;
java.util.regex.Pattern p = java.util.regex.Pattern.compile(emailRegex);
java.util.regex.Matcher m = p.matcher(email);
return m.matches();
}
Це найкращий метод:
public static boolean isValidEmail(String enteredEmail){
String EMAIL_REGIX = "^[\\\\w!#$%&’*+/=?`{|}~^-]+(?:\\\\.[\\\\w!#$%&’*+/=?`{|}~^-]+)*@(?:[a-zA-Z0-9-]+\\\\.)+[a-zA-Z]{2,6}$";
Pattern pattern = Pattern.compile(EMAIL_REGIX);
Matcher matcher = pattern.matcher(enteredEmail);
return ((!enteredEmail.isEmpty()) && (enteredEmail!=null) && (matcher.matches()));
}
Джерела: - http://howtodoinjava.com/2014/11/11/java-regex-validate-email-address/
Іншим варіантом є використання валідатора електронної пошти Hibernate , використовуючи примітку @Email
або використовуючи клас валідатора програмно, наприклад:
import org.hibernate.validator.internal.constraintvalidators.hv.EmailValidator;
class Validator {
// code
private boolean isValidEmail(String email) {
EmailValidator emailValidator = new EmailValidator();
return emailValidator.isValid(email, null);
}
}
Ось мій прагматичний підхід, де я просто хочу розумно чітких адрес blah @ домену, використовуючи допустимі символи з RFC. Адреси потрібно попередньо перетворити на малі регістри.
public class EmailAddressValidator {
private static final String domainChars = "a-z0-9\\-";
private static final String atomChars = "a-z0-9\\Q!#$%&'*+-/=?^_`{|}~\\E";
private static final String emailRegex = "^" + dot(atomChars) + "@" + dot(domainChars) + "$";
private static final Pattern emailPattern = Pattern.compile(emailRegex);
private static String dot(String chars) {
return "[" + chars + "]+(?:\\.[" + chars + "]+)*";
}
public static boolean isValidEmailAddress(String address) {
return address != null && emailPattern.matcher(address).matches();
}
}