在一個許多文字的文本中查找你所需要的文字並不簡單,但是正則表達式讓查找字符變得非常優雅。
今天我們就來學一學Java的正則表達式。
第一步,介紹Java中如何利用上面的正則語法來構造正則表達式呢
看下面的例子
public static void main(String[] args) {
// 正則表達式
String regex = "";
// 編譯正則表達式
Pattern pattern = Pattern.compile(regex);
// 被匹配的字符串
String str = "b";
// 設置被匹配的字符串
Matcher matcher = pattern.matcher(str);
// 匹配方式
// 全部匹配
if (matcher.matches()) {
// 如果匹配成功
System.out.println(str);
}
}
上面例子就是Java簡單的使用正則表達式的過程。首先我們主要學習正則表達式的用法
第二步 學習正則表達式
常用的正則字符
字符 匹配
x 字符 x
\\ 反斜線字符
\0n 帶有八進制值 0 的字符 n (0 <= n <= 7)
\0nn 帶有八進制值 0 的字符 nn (0 <= n <= 7)
\0mnn 帶有八進制值 0 的字符 mnn(0 <= m <= 3、0 <= n <= 7)
\xhh 帶有十六進制值 0x 的字符 hh
\uhhhh 帶有十六進制值 0x 的字符 hhhh
\t 製表符 ('\u0009')
\n 新行(換行)符 ('\u000A')
\r 回車符 ('\u000D')
\f 換頁符 ('\u000C')
\a 報警 (bell) 符 ('\u0007')
\e 轉義符 ('\u001B')
\cx 對應於 x 的控制符
字符 匹配
[abc] a、b 或 c(簡單類)
[^abc] 任何字符,除了 a、b 或 c(否定)
[a-zA-Z] a 到 z 或 A 到 Z,兩頭的字母包括在內(範圍)
[a-d[m-p]] a 到 d 或 m 到 p:[a-dm-p](並集)
[a-z&&[def]] d、e 或 f(交集)
[a-z&&[^bc]] a 到 z,除了 b 和 c:[ad-z](減去)
[a-z&&[^m-p]] a 到 z,而非 m 到 p:[a-lq-z](減去)
[ ] 代表邏輯框 默認爲或
字符 匹配
. 任何字符(與行結束符可能匹配也可能不匹配)
\d 數字:[0-9]
\D 非數字: [^0-9]
\s 空白字符:[ \t\n\x0B\f\r]
\S 非空白字符:[^\s]
\w 單詞字符:[a-zA-Z_0-9]
\W 非單詞字符:[^\w]
^ 行的開頭
$ 行的結尾
\b 單詞邊界
\B 非單詞邊界
\A 輸入的開頭
\G 上一個匹配的結尾
\Z 輸入的結尾,僅用於最後的結束符(如果有的話)
\z 輸入的結尾
X? X,一次或一次也沒有
X* X,零次或多次
X+ X,一次或多次
X{n} X,恰好 n 次
X{n,} X,至少 n 次
X{n,m} X,至少 n 次,但是不超過 m 次
X?? X,一次或一次也沒有
X*? X,零次或多次
X+? X,一次或多次
X{n}? X,恰好 n 次
X{n,}? X,至少 n 次
X{n,m}? X,至少 n 次,但是不超過 m 次
X?+ X,一次或一次也沒有
X*+ X,零次或多次
X++ X,一次或多次
X{n}+ X,恰好 n 次
X{n,}+ X,至少 n 次
X{n,m}+ X,至少 n 次,但是不超過 m 次
做個小程序來說明使用正則表達式的步驟
目的從一個網頁代碼的文本文件中提取出鏈接出來
<td>172</td><td>0</td><td><a href='?t=lock&id=69260885' class='lock'>禁止評論</a></td><td><a href='/postedit/69260885'>編輯</a> | <a href='?t=top&id=69260885'>置頂</a> | <a href='?t=del&id=69260885' name=del>刪除</a> | <a href='javascript:void(0);' onclick='javascript:return setcat(this,69260885);' class='cat'>分類</a></td></tr><tr class='altitem'><td class='tdleft'><a href='http://blog.csdn.net/a609733301/article/details/69259533' target=_blank>如何使用FastDFS上傳圖片</a><span class='gray'>(2017-04-13 22:34)</span></td><td> </td><td>170</td><td>0</td><td><a href='?t=lock&id=69259533' class='lock'>禁止評論</a></td><td><a href='/postedit/69259533'>編輯</a> | <a href='?t=top&id=69259533'>置頂</a> | <a href='?t=del&id=69259533' name=del>刪除</a> | <a href='javascript:void(0);' onclick='javascript:return setcat(this,69259533);' class='cat'>分類</a></td></tr><tr><td class='tdleft'>
<a href='http://blog.csdn.net/a609733301/article/details/69258951' target=_blank>數據結構與算法之高級排序(希爾/堆)<十一></a><span class='gray'>(2017-04-09 15:53)</span></td><td> </td><td>98</td><td>0</td><td><a href='?t=lock&id=69258951' class='lock'>禁止評論</a></td><td><a href='/postedit/69258951'>編輯</a> | <a href='?t=top&id=69258951'>置頂</a> | <a href='?t=del&id=69258951' name=del>刪除</a> | <a href='javascript:void(0);' onclick='javascript:return setcat(this,69258951);' class='cat'>分類</a></td></tr><tr class='altitem'><td class='tdleft'><a href='http://blog.csdn.net/a609733301/article/details/69258965' target=_blank>數據結構與算法之基礎排序(冒泡/插入/選擇)<十></a><span class='gray'>(2017-04-09 15:51)</span></td><td> </td><td>99</td><td>0</td><td><a href='?t=lock&id=69258965' class='lock'>禁止評論</a></td>
<td><a href='/postedit/69258965'>編輯</a> | <a href='?t=top&id=69258965'>置頂</a> | <a href='?t=del&id=69258965' name=del>刪除</a> | <a href='javascript:void(0);' onclick='javascript:return setcat(this,69258965);' class='cat'>分類</a></td></tr><tr><td class='tdleft'>
<a href='http://blog.csdn.net/a609733301/article/details/69258958' target=_blank>數據結構與算法之高級排序(快速/歸併)<十二></a><span class='gray'>(2017-04-09 15:50)</span></td>
<td> </td><td>106</td><td>0</td><td><a href='?t=lock&id=69258958' class='lock'>禁止評論</a></td><td><a href='/postedit/69258958'>編輯</a> | <a href='?t=top&id=69258958'>置頂</a> | <a href='?t=del&id=69258958' name=del>刪除</a> | <a href='javascript:void(0);' onclick='javascript:return setcat(this,69258958);' class='cat'>分類</a></td></tr><tr class='altitem'><td class='tdleft'><a href='http://blog.csdn.net/a609733301/article/details/69258919' target=_blank>數據結構與算法之優先隊列<九></a><span class='gray'>(2017-04-07 17:55)</span></td><td> </td><td>110</td><td>0</td><td><a href='?t=lock&id=69258919' class='lock'>禁止評論</a></td><td><a href='/postedit/69258919'>編輯</a> | <a href='?t=top&id=69258919'>置頂</a> | <a href='?t=del&id=69258919' name=del>刪除</a> | <a href='javascript:void(0);' onclick='javascript:return setcat(this,69258919);' class='cat'>分類</a>
</td></tr><tr><td class='tdleft'><a href='http://blog.csdn.net/a609733301/article/details/69258858' target=_blank>數據結構與算法之散列(分離鏈接法)<七></a><span class='gray'>(2017-04-07 17:39)</span></td><td> </td>
<td>131</td><td>0</td><td><a href='?t=lock&id=69258858' class='lock'>禁止評論</a></td><td><a href='/postedit/69258858'>編輯</a> | <a href='?t=top&id=69258858'>置頂</a> | <a href='?t=del&id=69258858' name=del>刪除</a> | <a href='javascript:void(0);' onclick='javascript:return setcat(this,69258858);' class='cat'>分類</a></td></tr><tr class='altitem'><td class='tdleft'><a href='http://blog.csdn.net/a609733301/article/details/69258910' target=_blank>數據結構與算法之散列(線性/平方/雙平方探測法)<八></a><span class='gray'>(2017-04-07 17:37)</span></td><td> </td><td>116</td><td>0</td><td><a href='?t=lock&id=69258910' class='lock'>禁止評論</a></td><td><a href='/postedit/69258910'>編輯</a> | <a href='?t=top&id=69258910'>置頂</a> | <a href='?t=del&id=69258910' name=del>刪除</a> | <a href='javascript:void(0);' onclick='javascript:return setcat(this,69258910);' class='cat'>分類</a></td></tr>
第一步確定正則表達式
分析過程
首先觀察鏈接的格式
http://blog.csdn.net/a609733301/article/details/69258919
根據需求找出不變的部分
這裏爲了使匹配稍微複雜點不設置不變得部分
因此可以初步確定格式
**://***.****.***/***/***/***/***
這樣的格式
將變化的部分裝化成正則表達式
一步一步來
首先根據需求來確定對各個變化部分是否有約束
爲了複雜我儘量加點約束
我想匹配http或者https以及ftp這幾種特定的首部
[(http)(https)(ftp)]
爲了方便直接可以
\\w{3,5}+ 至少三個不超過5個的字符 代表***
\\w{3,5}+:// 代表**://
接下來對於網址
直接可以
(\\w+\\.)+ 幾個字符加上一個.的形式出現多次 代表***.****.
(\\w+/)+ 幾個字符加上一個/的形式出現多次 代表 ***/***/
\\w+ 代表最後的幾個字符 ***
最終正則表達式是
\\w{3,5}+://(\\w+\\.)+(\\w+/)+\\w+
對正則表達式進行優化(會使其更難與閱讀)
\\w{3,5}+://(\\w+[\\./])+\\w+
確定好正則表達式後開始匹配
public static void main(String[] args) {
//獲取指定匹配文件
File file = new File("F:/JavaCode/JavaResource/JavaSourceCode/src/test/text.txt");
//創建存儲文件
File file1 = new File("F:/JavaCode/JavaResource/JavaSourceCode/src/test/text1.txt");
//創建存儲字符串
StringBuffer stringBuffer = new StringBuffer();
//編譯正則表達式
Pattern pattern = Pattern.compile("\\w{3,5}+://(\\w+[\\./])+\\w+");
try {
//文件讀取對象
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
//文件寫入對象
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file1));
//讀取文件直到末尾
while (bufferedReader.ready()) {
//一行一行的讀
String readLine = bufferedReader.readLine();
//匹配這一行
Matcher matcher = pattern.matcher(readLine);
//匹配到結果
while (matcher.find()) {
//將匹配的結果存入字符串中
stringBuffer.append(matcher.group());
stringBuffer.append('\n');
}
}
//將匹配字符存入文件
bufferedWriter.write(new String(stringBuffer));
bufferedReader.close();
bufferedWriter.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
結果
http://blog.csdn.net/a609733301/article/details/69259533
http://blog.csdn.net/a609733301/article/details/69258951
http://blog.csdn.net/a609733301/article/details/69258965
http://blog.csdn.net/a609733301/article/details/69258958
http://blog.csdn.net/a609733301/article/details/69258919
http://blog.csdn.net/a609733301/article/details/69258858
http://blog.csdn.net/a609733301/article/details/69258910
總結
正則表達式的使用
1.首先是根據需求來確定匹配字符的不變與變化部分
2.將變化部分根據約束一步一步替換成正則表達式。
3.總表達式可以根據情況進行優化
提示
不可能一次就完美匹配到結果,較好的方法是先粗糙匹配,再逐漸細膩化。