说明:
1。电子邮件原来保存在excel文件中,人工复制到mailist.txt文件中,每一行都自然换行。 2。现存不少问题,包括:
1)有特殊字符,例如 “/”,分号,中文字符等。
例如:[email protected]/[email protected]
这种情况下,以“/”为界,实际等于清理出来两个email。 类似的情况还有:
a)[email protected];[email protected]
b) [email protected] <[email protected]>
c) [email protected]或 [email protected]
等等,不胜枚举。
2)首尾有空字符,要求清除空字符
例如将 "[email protected] " 处理为 "[email protected]" 3)有大量重复邮件地址,要求清除重复的地址。 4)有错误的邮件地址,这样的地址,如果不易判断,则放入另一个文件(error.txt)。例如:邮件“[email protected]” 5)无符号连写
例如: [email protected]@advanceplastics.com
这里实际是两个邮件地址,中间有一个 or,这样的地址,如果不易判断,则放入另一个文件(error.txt)。 再例如:[email protected]@attbi.com
这里也是两个地址,中间也是有一个 “or”。
再例如:[email protected]@[email protected] 这里实际是3个地址,这样的地址,如果不易判断,则放入另一个文件。 6)不是每一行都有地址的,有时会有空行。(excel文件中该行记录的email栏目本来就是空的)。如果遇到空行,则要求删除空行。 7)邮件域名不一定是.com, .net 之类结尾。域名来自世界各地,例如 ".it", ".ae", ".se"等。 8)有可能是完全没有@字符,例如 braunsberger.at,或者 "1234"这样的数字或一些英文字串。这样的记录,应当删除。 9)email记录数以十万计。
3。清洗后的邮件列表,还是保存为每个email之后自然换行(即象从excel中复制到txt文件时那样)。
4。最后得出两个文件:
error.txt: 保存无法处理的错误邮件字符串
newmailist.txt: 处理完的邮件。
以下是一段email范例:
[email protected]/[email protected] [email protected]
[email protected]
[email protected]
842234
[email protected]
hello world
[email protected]
[email protected]
[email protected]@[email protected]
[email protected]@hotmail.com
[email protected];[email protected]
[email protected]&[email protected]
[email protected]/[email protected]
[email protected],[email protected]
[email protected][email protected]
[email protected]@aol.com
[email protected], [email protected], [email protected]
1。电子邮件原来保存在excel文件中,人工复制到mailist.txt文件中,每一行都自然换行。 2。现存不少问题,包括:
1)有特殊字符,例如 “/”,分号,中文字符等。
例如:[email protected]/[email protected]
这种情况下,以“/”为界,实际等于清理出来两个email。 类似的情况还有:
a)[email protected];[email protected]
b) [email protected] <[email protected]>
c) [email protected]或 [email protected]
等等,不胜枚举。
2)首尾有空字符,要求清除空字符
例如将 "[email protected] " 处理为 "[email protected]" 3)有大量重复邮件地址,要求清除重复的地址。 4)有错误的邮件地址,这样的地址,如果不易判断,则放入另一个文件(error.txt)。例如:邮件“[email protected]” 5)无符号连写
例如: [email protected]@advanceplastics.com
这里实际是两个邮件地址,中间有一个 or,这样的地址,如果不易判断,则放入另一个文件(error.txt)。 再例如:[email protected]@attbi.com
这里也是两个地址,中间也是有一个 “or”。
再例如:[email protected]@[email protected] 这里实际是3个地址,这样的地址,如果不易判断,则放入另一个文件。 6)不是每一行都有地址的,有时会有空行。(excel文件中该行记录的email栏目本来就是空的)。如果遇到空行,则要求删除空行。 7)邮件域名不一定是.com, .net 之类结尾。域名来自世界各地,例如 ".it", ".ae", ".se"等。 8)有可能是完全没有@字符,例如 braunsberger.at,或者 "1234"这样的数字或一些英文字串。这样的记录,应当删除。 9)email记录数以十万计。
3。清洗后的邮件列表,还是保存为每个email之后自然换行(即象从excel中复制到txt文件时那样)。
4。最后得出两个文件:
error.txt: 保存无法处理的错误邮件字符串
newmailist.txt: 处理完的邮件。
以下是一段email范例:
[email protected]/[email protected] [email protected]
[email protected]
[email protected]
842234
[email protected]
hello world
[email protected]
[email protected]
[email protected]@[email protected]
[email protected]@hotmail.com
[email protected];[email protected]
[email protected]&[email protected]
[email protected]/[email protected]
[email protected],[email protected]
[email protected][email protected]
[email protected]@aol.com
[email protected], [email protected], [email protected]
lz可以试一下正则去匹配邮件格式,然后再截取:比如一般的邮件格式是这样的:[email protected]
也就是说@符前面一般就是数字或字母,后面则是 数字或字母 + . +数字或字母。
楼主先用正则把文件匹配成规则点的,在用上面的匹配一下。 似乎还是有点麻烦
2、如果email.txt文件不大,20000行内的话,70%以上没有规律话。找人,手工先整理
3、email.txt很大,一个规律分解一次,然后把正确提取,然后下一个规律分解。少量就手工处理吧。
package test.parse;import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;public class Analyze { private static Set<String> set = new HashSet<String>();
private static String[] seps = {"/",";","或",","};
/**
* 返回是否是正常的email
* 是否包含有多个"@"
* @param str
* @return
*/
public boolean isMultiMail(String str){
if(str != null&&str.indexOf("@")!=str.lastIndexOf("@"))
return true;
else
return false;
}
/**
* 是否包含有"@"
* @param str
* @return
*/
public boolean isMail(String str){
if(str != null && str.contains("@"))
return true;
else
return false;
}
/**
* 按照分隔符分割串,同时去掉最后的空格
* 将结果存储在Set中便于删除重复的email(在set中的一定是符合要求的email)
* @param str
* @param seps
* @return 解析后的串,用\n分隔;如果是没有符合要求的返回null
*/
public String parseLine(String str,String[] seps,Set<String> set){
String normaRresult = "";
String errorResult = "";
str = str==null?"":str.trim();
for(int i = 0;i < seps.length; i++){
if(str.contains(seps[i])){
String[] s = str.split(seps[i]);
for(int j = 0;j < s.length&&isMail(s[j])&&!set.contains(s[j]); j++){
if(isMultiMail(s[j]))
errorResult = s[j].trim() + "\n";
else{
normaRresult += s[j].trim() + "\n";
set.add(s[j].trim());
}
}
if(!"".equals(errorResult))
errorResult = errorResult.substring(0,errorResult.lastIndexOf("\n"));
if(!"".equals(normaRresult))
normaRresult = normaRresult.substring(0,normaRresult.lastIndexOf("\n"));
}
}
if("".equals(normaRresult) && "".equals(errorResult)){
if(isMail(str)){
if(isMultiMail(str))
errorResult += str;
else
if(!set.contains(str)){
set.add(str);
normaRresult += str;
}
}
}
return "normal:"+normaRresult+";"+"error:"+errorResult;
}
public String getNormal(String str){
String[] strs = str.split(";");
if(strs.length < 2)
return "";
else{
String[] temp = strs[0].split(":");
if(temp.length <2)
return "";
else
return temp[1];
}
}
public String getError(String str){
String[] strs = str.split(";");
if(strs.length < 2)
return "";
else{
String[] temp = strs[1].split(":");
if(temp.length <2)
return "";
else
return temp[1];
}
}
/**
* 解析的方法
* @param filePath
* @param newmailPath
* @param errorPath
* @throws IOException
*/
public void parse(String filePath,String newmailPath,String errorPath) throws IOException{
BufferedReader br = new BufferedReader(new FileReader(filePath));
BufferedWriter normalbw = new BufferedWriter(new FileWriter(newmailPath));
BufferedWriter errorbw = new BufferedWriter(new FileWriter(errorPath));
String str = null;
try {
while(true){
str = br.readLine();
if(str == null || "".equals(str))
break;
str = parseLine(str,seps,set);
String normal = getNormal(str);
String error = getError(str);
if(!"".equals(normal))
normalbw.write(normal+"\n");
if(!"".equals(error))
errorbw.write(error+"\n");
}
} catch (IOException e) {
e.printStackTrace();
}finally{
if(br!= null)
br.close();
if(normalbw != null)
normalbw.close();
if(errorbw != null)
errorbw.close();
}
}
}下面的是测试程序:package test.parse;import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import junit.framework.TestCase;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;public class TestAnalyze extends TestCase{
public static Set<String> set = new HashSet<String>();
public static String[] seps = {"/",";","或"};
public Analyze analyze = new Analyze();
@Before
public void setUp() throws Exception {
} @After
public void tearDown() throws Exception {
} @Test
public void testIsMultiMail() {
String str ="[email protected]@[email protected]";
boolean result = analyze.isMultiMail(str);
assertEquals(true, result);
str = "";
result = analyze.isMultiMail(str);
assertEquals(false, result);
str = null;
result = analyze.isMultiMail(str);
assertEquals(false, result);
} @Test
public void testIsMail() {
String str = "[email protected]";
boolean result = analyze.isMail(str);
assertEquals(true, result);
str = "";
result = analyze.isMail(str);
assertEquals(false, result);
str = null;
result = analyze.isMail(str);
assertEquals(false, result);
} @Test
public void testParseLine() {
String str = null;
String result = null;
str = "[email protected]/[email protected]";
result = analyze.parseLine(str, seps, set);
System.out.println(result);
str = "[email protected]";
result = analyze.parseLine(str, seps, set);
System.out.println(result);
str = "[email protected] ";
result = analyze.parseLine(str, seps, set);
System.out.println(result);
str = "[email protected]@[email protected]";
result = analyze.parseLine(str, seps, set);
System.out.println(result);
str = "";
result = analyze.parseLine(str, seps, set);
System.out.println(result);
} public void testGetNormal(){
String str = null;
String result = null;
str = "normal:[email protected];error:";
result = analyze.getNormal(str);
System.out.println(result);
str = "normal:;error:";
result = analyze.getNormal(str);
System.out.println(result);
str = "";
result = analyze.getNormal(str);
System.out.println(result);
}
public void testGetError(){
String str = null;
String result = null;
str = "normal:;error:[email protected]@[email protected]";
result = analyze.getError(str);
System.out.println(result);
str = "normal:;error:";
result = analyze.getError(str);
System.out.println(result);
str = "";
result = analyze.getError(str);
System.out.println(result);
}
public void testParse() throws IOException{
String filePath = "E:/a8root/parse/mailist.txt";
String newmailPath = "E:/a8root/parse/newmailist.txt";
String errorPath = "E:/a8root/parse/error.txt";
analyze.parse(filePath, newmailPath, errorPath);
}
}
1。
str = "normal:;error:[email protected]@[email protected]";
result = analyze.getError(str);
System.out.println(result); 像这个,最好能做出3个email:
[email protected]
[email protected]
[email protected].
private static String[] seps = {"/",";","或",","}; 还会有这样的情况,如何应对:?
1) 空格,或者其他中文标点符号,全角也是存在的
2) [email protected] and [email protected]
3) 不一定是“或”字,可能有其他中文字。
4) 还有说明中提到的这样的情况 [email protected] <[email protected]>
5)或者可能这样:(“<”之前的空格没有了)[email protected]<[email protected]>
这些email出现的问题,无非是人工录入email时出现的瑕疵,用人脑基本都能够判断并作出正确分拣,但用程序则比较麻烦。所以征求各位高见。
1。最多见的情况是 一个email一行,后面跟着空格,或者没有空格2。多个email在同一行的情况比较少见,人脑能判断,但程序麻烦,例如:str = "normal:;error:[email protected]@[email protected]";
result = analyze.getError(str);
System.out.println(result); 像这个,最好能做出3个email:
[email protected]
[email protected]
[email protected] 问题是存在一些国家后缀名,例如:.cn .fr . sa 等
以及多级域名,例如: [email protected]。关于你提到的明确分隔符的问题,其实是这样:合法的email字符就那些,非法的字符就是分隔符,不能逗号还是句号,不论全角还是半角,不论一个空格符还是换行符。最大的问题在于 “.”号, 正如2中所描述的那样的问题, 不易判断是否已经结束。
楼主提出问题的解决思想(主要都是正则表达式.).
这些问题我在下面分别提供了解决思想,在这里做一个总结性的解决方案:
把整个问题分作两部分进行操作:首先抽取出所有的Email,然后对错误的,重复的,不规范的Email进行分拣.
抽取Email的时候可以通过构造多个正则表达式,全面的过滤文本,抽取到Email,每行一个写入到一个新的文本中.
分拣的时候,主要是对连写,格式不正确等的分割,所以使用split()或者逗号表达式(不推荐),当然,这里使用正则表示还是最好的选择.
去除重复的时候个人感觉采用set比较容易实现,但是对于数据量比较大的情况下,可以考虑采用缓冲机制解决.
1)有特殊字符,例如 “/”,分号,中文字符等。
例如:[email protected]/[email protected]
这种情况下,以“/”为界,实际等于清理出来两个email。 解决:把所有可能出现的这种分割符拿出来,然后split,或者逗号表达式解决.
类似的情况还有:
a)[email protected];[email protected]
b) [email protected] <[email protected]>
c) [email protected]或 [email protected]
等等,不胜枚举。
2)首尾有空字符,要求清除空字符
例如将 "[email protected] " 处理为 "[email protected]" 解决:抽取出来的email是每行一个,那么每行trim()3)有大量重复邮件地址,要求清除重复的地址。 解决:这个可以把你已经分拣过的email放到一个set中.让set为你过滤重复4)有错误的邮件地址,这样的地址,如果不易判断,则放入另一个文件(error.txt)。例如:邮件“[email protected]” 解决:给出正确邮件的格式(正则表达式Pattern规范email格式),这个问题不应该出现在分拣阶段,在抽取email的时候就应该过滤掉.5)无符号连写
例如: [email protected]@advanceplastics.com
这里实际是两个邮件地址,中间有一个 or,这样的地址,如果不易判断,则放入另一个文件(error.txt)。
再例如:[email protected]@attbi.com
这里也是两个地址,中间也是有一个 “or”。
再例如:[email protected]@[email protected] 这里实际是3个地址,这样的地址,如果不易判断,则放入另一个文件。 解决:和第四个问题一样,如果在抽取的时候就已经有一个好的Pattern,那么就不会有这个问题的出现.
6)不是每一行都有地址的,有时会有空行。(excel文件中该行记录的email栏目本来就是空的)。如果遇到空行,则要求删除空行。 解决: 写个正则表达式,过滤掉所有的空行.让我们拿到的email必须是每行一个.7)邮件域名不一定是.com, .net 之类结尾。域名来自世界各地,例如 ".it", ".ae", ".se"等。 解决:这个没有固定的格式是没有办法由程序自动判断,只能由程序员把所有可能的规范写入Pattern8)有可能是完全没有@字符,例如 braunsberger.at,或者 "1234"这样的数字或一些英文字串。这样的记录,应当删除。 解决:还是在抽取email的时候就应该解决的,一个好的Pattern可以解决这些问题.9)email记录数以十万计。 数据量大带来的效率问题主要是对于去除重复影响比较大,所以,可以考虑使用其他更好的算法或程序设计模式解决去除重复的问题.
// TODO Auto-generated constructor stub
this.str=str;
file1 = new File(filename1);
file2 = new File(filename2);
file3 = new File(filename3);
file4 = new File(filename4);
if(!file1.exists()){
try {
file1.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
filewriter1 = new FileWriter(file1,false);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(!file2.exists()){
try {
file2.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
filewriter2 = new FileWriter(file2,false);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(!file3.exists()){
try {
file3.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
filewriter3 = new FileWriter(file3,false);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(!file4.exists()){
try {
file4.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
filewriter4 = new FileWriter(file4,false);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public DNSLookUP(String str) {
// TODO Auto-generated constructor stub
this.str=str;
}
/**
* @param args
*/
public static void main(String[] args) {
File nfile = new File("D:/DNSLookUP/site");
File[] files=nfile.listFiles();
String back =".txt";
for(int i=0;i<files.length;i++){
String strname = files[i].getPath().substring(0,files[i].getPath().length()-4);
System.out.println(strname+"A"+back);
new DNSLookUP("",strname+"A"+back,strname+"B"+back,strname+"C"+back,strname+"D"+back).lookup(readFile(files[i]));
}
System.out.println("结束!!"); }
//验证DNS的真实性 由于数据量的庞大,用单线程可能需要一天的时间,所以每一个DNS都用一个线程去验证
public boolean lookup(Set<String> set){
ExecutorService pool = Executors.newCachedThreadPool();
List<Future<Integer>> taskList = new ArrayList<Future<Integer>>();
int n = 0;
for(String str:set){
System.out.println("添加一个线程");
taskList.add(pool.submit(new DNSLookUP(str)));
if((++n>=50&&n%50==0)||set.size()==n){
List<Future<Integer>> finishList = new ArrayList<Future<Integer>>();
while(true){
for(Future<Integer> f:taskList){
try {
if(finishList.contains(f)){
continue;
}
f.get(10, TimeUnit.MILLISECONDS);
finishList.add(f);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TimeoutException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
}
}
if(finishList.size()==n){
if(nset.size()>=200||set.size()==n){
writeFile();
}
break;
}
try {
Thread.sleep(20);
System.out.println(n);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
pool.shutdown();
//List<String> list = new ArrayList<String>();
//list.addAll(nset);
//Collections.sort(list, this);
try {
filewriter1.close();
filewriter2.close();
filewriter3.close();
filewriter4.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}
//读文件,返回一个set
public static Set<String> readFile(File file){
//File file= new File(filename);
Set<String> set = new HashSet<String>();
if(file.exists()){
try {
BufferedReader buff = new BufferedReader(new FileReader(file));
String str = null;
try {
while(null!=(str=buff.readLine())){
set.add(str);
System.out.println(str);
}
buff.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return set;
}
//写文件
public static boolean writeFile(){
if(filewriter1==null||filewriter2==null||filewriter3==null||filewriter4==null){
return false;
}
StringBuilder strbuilder = new StringBuilder();
StringBuilder strbuilder126 = new StringBuilder();
StringBuilder strdomain1 = new StringBuilder();
StringBuilder strdomain2 = new StringBuilder();
//写正确的DNS
if(domainset1!=null){
for(String s:domainset1){
strdomain1.append(s).append("\r\n");
}
try {
filewriter3.write(strdomain1.toString());
filewriter3.flush();
domainset1.clear();
//return true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//写错误的DNS
if(domainset2!=null){
for(String s:domainset2){
strdomain2.append(s).append("\r\n");
}
try {
filewriter4.write(strdomain2.toString());
filewriter4.flush();
domainset2.clear();
//return true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//写正确的EMAIL
if(nset!=null){
for(String s:nset){
if(s.indexOf("@163.com")>-1 || s.indexOf("@126.com")>-1){
strbuilder126.append(s).append("\r\n");
}else{
strbuilder.append(s).append("\r\n");
}
}
try {
filewriter1.write(strbuilder126.toString());
filewriter2.write(strbuilder.toString());
filewriter1.flush();
filewriter2.flush();
nset.clear();
return true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return false;
}
/*public int compare(String o1, String o2) {
// TODO Auto-generated method stub
String str1 = o1.substring(o1.indexOf('@'));
String str2 = o2.substring(o2.indexOf('@'));
return str1.compareTo(str2);
}*/
//线程调用
public Integer call() throws Exception {
// TODO Auto-generated method stub
String nstr = str.substring(str.indexOf('@')+1);
Boolean bool = map.get(nstr);
if(null==bool){
try {
InetAddress.getByName(nstr);
map.put(nstr, true);
nset.add(str);
if(!domainset1.contains(nstr)){
domainset1.add(nstr);
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
System.err.println(nstr);
map.put(nstr, false);
if(!domainset2.contains(nstr)){
domainset2.add(nstr);
}
}
}else{
if(bool){
nset.add(str);
}
}
return 0;
}}