Posted on 2007-04-21 01:21
Exiler 閱讀(1149)
評論(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);
}
}