Java에 적합한 이메일 주소 유효성 검사 라이브러리는 무엇입니까? Commons Validator에 대한 대안이 있습니까?
Java에 적합한 이메일 주소 유효성 검사 라이브러리는 무엇입니까? Commons Validator에 대한 대안이 있습니까?
답변:
Apache Commons는 일반적으로 견고한 프로젝트로 알려져 있습니다. 그러나 실제 이메일인지 확인하고 소유자가 사이트에서 사용하기를 원하는 경우에도 확인 이메일을 주소로 보내야합니다.
편집 : 도메인에 너무 제한적인 버그 가있어 새 TLD에서 유효한 전자 메일을받지 못합니다.
이 버그는 commons-validator 버전 1.4.1의 03 / Jan / 15 02:48에서 해결되었습니다.
EmailValidator
클래스는 확인을 위해 전자 메일 메시지를 보내지 않습니다.
공식 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의 클래스를 기반으로하지만 많은 개선 사항이 있으며 몇 가지 버그가 수정되었습니다. 아파치 라이선스.
Java에서 가장 유능한 전자 메일 파서라고 생각하지만 아직 어떤 언어로도 유능한 전자 메일 파서가 하나도 보이지 않습니다. 그것은 렉서 스타일 파서가 아니지만 복잡한 자바 정규 표현식을 사용하므로 가능한 효율적이지 않지만 회사는 100 억 개 이상의 실제 주소를 파싱했습니다. 고성능으로 확실히 사용할 수 있습니다. 상태. 아마도 일년에 한 번은 정규 표현식 스택 오버플로를 유발하는 주소에 부딪 칠 수 있지만 (수많은 따옴표와 괄호 등으로 수백 또는 수천 자 길이의 스팸 주소입니다).
RFC 2822 및 관련 사양은 전자 메일 주소와 관련하여 실제로 매우 허용되므로 이와 같은 클래스는 대부분의 용도에 과도합니다. 예를 들어, 다음은 사양, 공백 및 모두에 따른 합법적 인 주소입니다.
"<bob \" (here) " < (hi there) "bob(the man)smith" (hi) @ (there) example.com (hello) > (again)
메일 서버는이를 허용하지 않지만이 클래스는이를 구문 분석하고 사용 가능한 양식으로 다시 작성할 수 있습니다.
기존 Java 이메일 파서 옵션이 내구성이 부족하다는 것을 발견했습니다 (즉, 모든 유효한 주소를 구문 분석 할 수 없음).이 클래스를 작성했습니다.
코드는 잘 문서화되어 있으며 특정 전자 메일 양식을 허용하거나 허용하지 않는 변경하기 쉬운 옵션이 많이 있습니다. 또한 주소의 특정 부분 (왼쪽, 오른쪽, 개인 이름, 주석 등)에 액세스하고 사서함 목록 헤더를 구문 분석 / 확인하고 반환 경로를 구문 분석 / 확인하는 많은 방법을 제공합니다. (헤더 중에서 고유함) 등.
작성된 코드는 javamail 의존성을 갖지만, 사소한 기능을 원하지 않는 경우 쉽게 제거 할 수 있습니다.
왜 아무도 @Email
Hibernate Validator의 추가 제약 조건을 생각해 냈는지 궁금 합니다. 유효성 검사기 자체는 EmailValidator
입니다.
Les Hazlewood는 Java 정규식을 사용하여 매우 철저한 RFC 2822 호환 이메일 검사기 클래스를 작성했습니다. 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()]);
}
}
그리고 다른 tld에 대한 정규식 패턴이있는 validIDNs.xml (너무 포함하기에는 너무 큼)
<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));
}
}
아파치 커먼즈에 대한 대안이 많이 있지만 아파치 커먼즈 구현 자체 와 같이 구현은 기본적으로 초보적 이며 다른 경우에는 잘못되었습니다.
나는 또한 간단한 '비 제한적'정규식에서 멀리 떨어져있을 것입니다. 그런 것은 없습니다. 예를 들어 @는 문맥에 따라 여러 번 허용됩니다 . 필요한 것이 있는지 어떻게 알 수 있습니까? 이메일이 유효하더라도 간단한 정규식으로 이해하지 못합니다. 아무것도 더 복잡 하게 오류가 발생하기 쉬운 또는 포함 숨겨진 성능 살인자 . 어떻게 같은 것을 유지하려고 이 ?
내가 아는 유일한 RFC 호환 정규식 기반 유효성 검사기 는 '정제 된'정규식으로 이름이 Dragons.java 인 email-rfc2822 유효성 검사기 입니다 . 최신 요구 사항에 충분히 적합하지만 이전 RFC-2822 사양 만 지원 합니다 (RFC-5322 는 이미 일상적인 사용 사례 범위를 벗어난 영역에서 업데이트 ).
그러나 실제로 원하는 것은 문자열을 올바르게 구문 분석하고 RFC 문법에 따라 구성 요소 구조로 나누는 렉서 입니다. EmailValidator4J 는 그 점에서 유망한 것처럼 보이지만 여전히 젊고 제한적입니다.
또 다른 옵션은 Mailgun의 전투 테스트 유효성 검사 웹 서비스 또는 Mailboxlayer API 와 같은 웹 서비스를 사용하는 것입니다 (첫 번째 Google 결과를 얻었습니다). RFC를 엄격하게 준수하지는 않지만 현대적인 요구에 적합합니다.
현재 Apache Commons Validator 버전은 1.3.1 입니다.
유효성을 검사하는 클래스는 org.apache.commons.validator.EmailValidator입니다. 은퇴 한 Jakarta ORO 프로젝트 에서 가져온 org.apache.oro.text.perl.Perl5Util에 대한 가져 오기 가 있습니다 .
BTW, 1.4 버전이 있음을 발견했습니다 . API 문서는 다음 과 같습니다 . 이 사이트 에는 "최종 게시일 : 2008 년 3 월 5 일 | 버전 : 1.4-SNAPSHOT"이라고되어 있지만 최종적인 것은 아닙니다. 자신을 구축하고 (RELEASE가 아닌 스냅 샷임) 유일한 방법은 여기 에서 사용하거나 다운로드 하십시오 . 이는 1.4 년이 3 년 동안 (2008-2011) 최종되지 않았 음을 의미합니다. 이것은 아파치 스타일이 아닙니다. 더 나은 옵션을 찾고 있지만 매우 채택 된 옵션을 찾지 못했습니다. 잘 테스트 된 것을 사용하고 싶습니다. 버그를 피하고 싶지 않습니다.
이메일 주소로 이메일을 보내고 응답을 기다리는 데 시간이 걸리지 않는 한 완벽한 라이브러리 나 방법은없는 것 같습니다 (옵션이 아닐 수도 있음). 나는 여기 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);
}
}
RFC의 허용 가능한 문자를 사용하여 합리적인 별개의 blah @ 도메인 주소를 원하는 실용적인 방법이 있습니다. 주소는 미리 소문자로 변환해야합니다.
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();
}
}