Posted on 2007-04-21 01:21
Exiler 阅读(1135)
评论(0) 编辑 收藏
/**
* @author Solo
*
* 很久以前写的一道题目,昨天翻出来看了看,都有些忘记了,花了1个小时补上了注释
* 对于学习在Java中使用正则表达式有点帮助
* 将一个保存有ip地址与地区对照关系的文本文件导入到数据库时,
* 应该将其中的某些空格替换成逗号(,),即对于如下格式的文本文件内容:
* 起始IP 结束IP 地区
* ---------------------------------------------------------------
* 61.54.231.245 61.54.231.245 河南省安阳市 新世纪网吧
* 61.54.231.246 61.54.231.246 河南省安阳市 未知地区
* 61.54.231.9 61.54.231.247 河南省安阳市 红日网吧
* 61.54.231.248 61.54.231.248 河南省安阳市 安阳师范学院
* 61.54.231.249 61.54.231.249 河南省安阳市 黑蜘蛛网吧(师范学院附近)
* 应转换成下面的这种格式:
* 61.54.231.245,61.54.231.245,河南省安阳市 新世纪网吧
* 61.54.231.246,61.54.231.246,河南省安阳市 未知地区
* 61.54.231.247,61.54.231.247,河南省安阳市 红日网吧
* 61.54.231.248,61.54.231.248,河南省安阳市 安阳师范学院
* 61.54.231.249,61.54.231.249,河南省安阳市 黑蜘蛛网吧(师范学院附近)
* 任务:
* 阅读String.replaceAll方法的帮助,以及它提供的相关超链接,
* 了解该方法的用法后,编写一个java程序来自动实现上面的正则表达式替换,
* 将a.txt替换后的结果保存到b.txt文件中。
* 另外,我们在实现ip地区查询系统时,使用的是类似如下的sql语法:
* select 地区 from ip表 where 用户ip>起始IP and 用户ip<结束ip
* 通过这条sql语句就可以查询出用户ip所对应的地区结果。由于用户ip与起始
* ip和结束ip的比较属于字符串比较,如果用户ip为9.1.1.1,那么它与
* 61.54.231.245比较的结果就是前者大于后者,因为用户ip的第一个字符“9”
* 大于61.54.231.245中的第一个字符“6”。
* 现在请你想出一种解决办法,让上面的sql语句能够返回正确结果。
* 请按这种思路在你的程序中增加进行这种改变的正则表达式替换。
*/
import java.io.*;
import java.util.regex.*;
public class Ip
{
private static void fileIO(File f)
{
String strLine;
// 调用执行本程序的操作系统的标准换行符,意味着跨平台
String line = System.getProperty("line.separator");
try
{
// 输入流
FileInputStream fis = new FileInputStream(f);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr);
// 输出流
FileOutputStream fos = new FileOutputStream("c://b.txt");
OutputStreamWriter osw = new OutputStreamWriter(fos);
BufferedWriter bw = new BufferedWriter(osw);
/*
* 创建一个模式对象, 模式中编辑的正则表达式匹配分别是(200-249|250-255|001-199) 以匹配一个IP地址
*/
Pattern pattern = Pattern
.compile("((2[0-4]d|25[0-5]|[01]?dd?).){3}(2[0-4]d|25[0-5]|[01]?dd?)");
// 声明模式适配器
Matcher matcher;
// 循环读取文件中的每一行
while ((strLine = br.readLine()) != null)
{
/*
* String调用replaceAll方法匹配一个正则表达式找到一个位置,然后替换成逗号
*/
strLine = strLine.replaceAll("(?<=d)s+", ",");
// 用适配器加载一行字符串,并匹配模式
matcher = pattern.matcher(strLine);
// 如果在一行中能找到匹配的字符串则循环
while (matcher.find())
{
// 取一行中第一个能匹配的子字符串
String buf = matcher.group();
// 以"."分割成数字,然后分别补零,再合并
strLine = matcher.replaceAll(change(buf));
// 输入一行到文件,但不包括换行符
bw.write(strLine);
// 输入行分割符,即换行符
bw.write(line);
}
}
// 关闭输入流
br.close();
// 关闭输出流
bw.close();
}
// 捕获原始文件未找到异常
catch (FileNotFoundException e)
{
System.out.println("原始文件未找到");
}
// 捕获IO异常
catch (IOException e)
{
e.printStackTrace();
}
}
// 此方法用来接收一个分割出来的一个数字,将不足3位的补零后返回
private static String fill(String str)
{
// 不足3位的补零
while (str.length() < 3)
{
str = '0' + str;
}
// 返回补零后的字符串
return str;
}
private static String change(String buf)
{
// 缓冲字符串
String temp;
// 结果返回字符串
String ret;
// 以"."分割,存入字符串数组
String[] str = buf.split(".");
// 第一个数字不需要在前面加"."
ret = fill(str[0]);
// 从第2个数字开始,给每个数字前面分别再加上".",并且不足的补零
for (int i = 1; i < str.length; i++)
{
// 调用fill方法给不足3位的数字补零
temp = fill(str[i]);
// 每个数字加点后从新组装成一个
ret = ret + "." + temp;
}
// 返回结果字符串
return ret;
}
// 程序入口
public static void main(String[] args)
{
// 读原始文件
File f = new File("c://a.txt");
// 将原始文件传入fileIO方法,按要求加工
fileIO(f);
}
}