Премини към съдържанието
Владислав Господинов

Програма за намиране на валидни e-mail адреси.

Препоръчан отговор


Добър ден съфорумници и за много години! Имам една курсова работа за университета, която според мен си направих и си върви що годе добре ( :D) Просто седя и се чудя дали има и други по-лесни и удобни вариянти за решаването й. Заданието което ми е дадено е следното:

 

· приложението отваря файл за четене (в текстов режим) - пътят и името на файла са специфицирани в параметър от командния ред.

· Приложението открива и визуализира всички валидни email адреси, съдържащи се във файла.

· Проверката за валидност на email адреса да се извърши съгласно RFC3696.

· Да се използват регулярни изрази.

· Откритите, валидни email адреси да се визуализират на екрана

 

 

RFC3696  -     http://tools.ietf.org/html/rfc3696

 

Кодът който успях да направя: 

import java.io.File;import java.io.FileNotFoundException;import java.util.Scanner;public class EmailValidator {	public static void main(String[] args) {		if (args.length==0) System.out.println("Missing arguments!");		String path = args[0]+""+args[1];		Scanner readFile = null;		File file = new File(path);		try {			readFile = new Scanner(file);			String[] mails;			String mailRegEx = "^[_A-Za-z0-9!#$%&’*+-/=?^ ‘.{|}˜]{0,64}+@[A-Za-z0-9-]+(.[A-Za-z0-9-]+)*(.[A-Za-z]{2,})$";			while (readFile.hasNextLine()){				mails = readFile.nextLine().split("[ ]+");				for (String candidate : mails){					boolean isValid = candidate.matches(mailRegEx);					if (isValid) System.out.println(candidate);				}			}		} catch (FileNotFoundException fnf){			System.out.println("File "+path+" not found!");		} finally {			if (readFile != null){				readFile.close();			}		}	}}

Намирам грешка поради това че разделям стринга където намеря интервал. Докато в RFC3696 за локалната част се споменава че може да присъства и интервала.

 

Регулярният израз изглежда доста странно за разлика от всички които намирам в интернет за e-mail адреси, но това разбирам от RFC-то. Въпреки че не успявам да разбера точно за домайн част.

 

Също така в локалната част явно може да съдържа и ' коментари'  ( " , ) което също не ми се получава.

 

Въпреки всичко това ... върви :D

Редактирано от Владислав Господинов (преглед на промените)

Сподели този отговор


Линк към този отговор
Сподели в други сайтове

...

Здравейте !

 

За да избегнете описания по-горе от Вас проблем, защо не се опитате да разпишете кода, използвайки класовете Pattern и Matcher на java.util.regex пакета ?

Използването на String.matches() не е препоръчително, особено за този тип задача.

Използвайте изчитането на редовете от файла и приложете Pattern/Matcher обектите върху целия текст, а не върху split-нати данни.

 

За повече инфо: Тук и тук

 

Поздрави !

Сподели този отговор


Линк към този отговор
Сподели в други сайтове
Пробвай този код  :public boolean validateEmail(email){   // Input the string for validation   // String email = "xyz@.com";   // Set the email pattern string   Pattern p = Pattern.compile(".+@.+.[a-z]+");   // Match the given string with the pattern   Matcher m = p.matcher(email.getText());   // check whether match is found   boolean matchFound = m.matches();   StringTokenizer st = new StringTokenizer(email, ".");   String lastToken = null;   while (st.hasMoreTokens()) {      lastToken = st.nextToken();   }   if (matchFound && lastToken.length() >= 2      && email.length() - 1 != lastToken.length()) {      // validate the country code      return true;   }   else return false;}

Сподели този отговор


Линк към този отговор
Сподели в други сайтове

...

Здравейте !

 

Добре сте се ориентирали в ползването на Pattern/Matcher класовете, но кода идва и със съществени проблеми. 

 

Предложеният от Вас е израз позволява намирането на абсурдни (и неверни) e-mail адреси, които реално няма как да съществуват.

Освен това, защо ползвате StringTokenizer ? Логиката, по която го ползвате е сходна със String.split() !

Идеята на matcher-а е да се ползват matcher.find() и matcher.group(). В примера, който цитирах в първия си пост са дадени.

 

Освен това: 

 

 

public boolean matches()
Attempts to match the entire region against the pattern.

If the match succeeds then more information can be obtained via the start, end, and group methods.

Returns: true if, and only if, the entire region sequence matches this matcher's pattern

source

 

Matcher.matches() е абсолютно безполезен за извличане на e-mail-и от текст. За проверка бих се съгласил, но не и за търсене/извличане (каквото е условието на задачата).

 

По кода Ви:

public boolean validateEmail(email){ //Компилационна грешка - Няма зададен тип на параметъра email   // Input the string for validation   // String email = "xyz@.com";   // Set the email pattern string   Pattern p = Pattern.compile(".+@.+.[a-z]+"); //Изкоментирахме, че този regex е много слаб.   // Match the given string with the pattern   Matcher m = p.matcher(email.getText()); //String класа имплементира CharSequence интерфейса - email може да се подаде директно. Освен това - класа String няма метод getText() ...     // check whether match is found   boolean matchFound = m.matches(); // Това се ползва само на едно място. Защо му правите отделна променлива ?   StringTokenizer st = new StringTokenizer(email, "."); //Защо split-ваме по точка (".") ? Ние искаме да проверим валидност на целия e-mail, а не на някакви части от него, за които не сме сигурни какво биха представлявали.   String lastToken = null;   while (st.hasMoreTokens()) {      lastToken = st.nextToken();   }   if (matchFound && lastToken.length() >= 2      && email.length() - 1 != lastToken.length()) { //Безсмислено ... Защо се проверява само country code-а ?      // validate the country code      return true;   }   else return false;}

Прегледайте примерите, които съм приложил и ползвайте първоначално цитирания regex на автора, за извличането на e-mail адресите.

 

Поздрави !

Сподели този отговор


Линк към този отговор
Сподели в други сайтове

Пробвах с Patter/Matcher, но някъде по пътя имам грешка защото ми изписва че не намира валидни емайл адреси във файла който задавам. А това не е така от където след ,че имам най-вероятно грешка в регулярния израз, но не се изключва и възможноста за множество други грешки из кода. :D:P

import java.io.File;import java.io.FileNotFoundException;import java.util.Scanner;import java.util.regex.*;public class Pattern_Matcher_Test {	public static void main(String[] args) {		if (args.length==0) System.out.println("Missing arguments!");		String path = args[0]+""+args[1];		Scanner readFile = null;		File file = new File(path);		try {			readFile = new Scanner(file);			String mailRegEx = "^[_A-Za-z0-9-]+(.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(.[A-Za-z0-9-]+)*(.[A-Za-z]{2,})$";			Pattern RegEx = Pattern.compile(mailRegEx);			String match = "";			while (readFile.hasNextLine()){				Matcher regExMatcher = RegEx.matcher(readFile.nextLine());				while (regExMatcher.find()){					match = regExMatcher.group();					System.out.println("Found: "+match);				}				if (match == ""){					System.out.println("There are no matches!");				}			}		} 		catch (FileNotFoundException fnf){		System.out.println("File "+path+" not found!");		} 		finally {		if (readFile != null){			readFile.close();		}	}				}}

Сподели този отговор


Линк към този отговор
Сподели в други сайтове

...

 

Здравейте !

 

Поогледах regex-а Ви - той всъщност е проблема, да не намирате резултати.

Няколко думи, преди да пристъпя към предложението за regex, което сътворих ...

 

1) Поне за момента, не ми е известен такъв regex, който да успее да хване абсолютно всички e-mail адреси, които могат да съществуват по спецификацията на RFC-тата. Принципа в случая е да си измислите такъв, който да покрие или определен тип вид e-mail-и (да кажем такива, които са domain-specific) или да покрие по-разпространените e-mail-и, които могат да съществуват - да кажем далеч по - вероятно е да имаме email от вида myemail.mail@somedomain.bg, отколкото подобен на "my. unusual.mail"@example.com (тук се включват и кавичките за капак ... ).

 

2) Работата с regex-и не се води една от най-леките за системата, особено когато говорим за подобни match-вания. Колкото по - сложен е regex-а, толкова повече ресурси и време ще заминат.

 

3) Из мрежата има доста примери за реализирани e-mail regex-и, които се и ползват с Pattern/Matcher класовете. Ако предложените от мен не Ви устройват, можете да се поровите допълнително :)

 

4) Regex-а, който Ви давам със сигурност не е пълен, но ще мачне доста голяма част от адресите. Условно не съм разписал мачването по IP адрес за domain част - това го оставям да си го разпишете по Ваш избор, като ако имате нужда от помощ, ще Ви помогна. 

			String mailRegExWithSpace = "([-!#$%&'*+/0-9=?A-Z^_a-z{|}~]*[s])?(.?[-!#$%&'*+/0-9=?A-Z^_a-z{|}~])*@[a-zA-Z](-?[a-zA-Z0-9])*(.[a-zA-Z](-?[a-zA-Z0-9])*)+";			String mailRegExWithoutSpace = "(.?[-!#$%&'*+/0-9=?A-Z^_a-z{|}~])*@[a-zA-Z](-?[a-zA-Z0-9])*(.[a-zA-Z](-?[a-zA-Z0-9])*)+";			

Първия е случая, в който ще се улови и space-а, ако има такъв във името на локалната част. Втория е подобен на първия, като той няма да допусне наличие на space символа (т.е. подобен е на първия Ваш вариант). 

 

В момента regex-ите не ловят адреси, които имат IP за домейн. Ако все пак го искате, можете да погледнете тук какви предложения са дадени. Може да проверите и тук за още допълнителни неща.

 

P.S. Само regex-а за валидация на IPv6 адрес е покъртителен ...

 

Поздрави !

Сподели този отговор


Линк към този отговор
Сподели в други сайтове

Регистрирайте се или влезете в профила си за да коментирате

Трябва да имате регистрация за да може да коментирате това

Регистрирайте се

Създайте нова регистрация в нашия форум. Лесно е!

Нова регистрация

Вход

Имате регистрация? Влезте от тук.

Вход

×

Информация

Поставихме бисквитки на устройството ви за най-добро потребителско изживяване. Можете да промените настройките си за бисквитки, или в противен случай приемаме, че сте съгласни с нашите условия за ползване.