一、正則表達式概述
1、 概念:符合一定規則的表達式。
2、 作用:用於專門操作字符串。
3、 特點:用於一些特定的符號來表示一些代碼操作,這樣可以簡化書寫。所以學習正則表達式,就是在學習一些特殊符號的使用。
4、 好處:可以簡化對字符串的複雜操作。
5、 弊端:符合定義越多,正則越長,閱讀性越差。
構造 | 匹配 |
---|---|
字符 | |
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] |
POSIX 字符類(僅 US-ASCII) | |
\p{Lower} | 小寫字母字符:[a-z] |
\p{Upper} | 大寫字母字符:[A-Z] |
\p{ASCII} | 所有 ASCII:[\x00-\x7F] |
\p{Alpha} | 字母字符:[\p{Lower}\p{Upper}] |
\p{Digit} | 十進制數字:[0-9] |
\p{Alnum} | 字母數字字符:[\p{Alpha}\p{Digit}] |
\p{Punct} | 標點符號:!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ |
java.lang.Character 類(簡單的 java 字符類型) | |
---|---|
\p{javaLowerCase} | 等效於 java.lang.Character.isLowerCase() |
\p{javaUpperCase} | 等效於 java.lang.Character.isUpperCase() |
\p{javaWhitespace} | 等效於 java.lang.Character.isWhitespace() |
\p{javaMirrored} | 等效於 java.lang.Character.isMirrored() |
Unicode 塊和類別的類 | |
\p{InGreek} | Greek 塊(簡單塊)中的字符 |
\p{Lu} | 大寫字母(簡單類別) |
\p{Sc} | 貨幣符號 |
\P{InGreek} | 所有字符,Greek 塊中的除外(否定) |
[\p{L}&&[^\p{Lu}]] | 所有字母,大寫字母除外(減去) |
邊界匹配器 | |
^ | 行的開頭 |
$ | 行的結尾 |
\b | 單詞邊界 |
\B | 非單詞邊界 |
\A | 輸入的開頭 |
\G | 上一個匹配的結尾 |
\Z | 輸入的結尾,僅用於最後的結束符(如果有的話) |
\z | 輸入的結尾 |
Greedy 數量詞 | |
X? | X,一次或一次也沒有 |
X* | X,零次或多次 |
X+ | X,一次或多次 |
X{n} | X,恰好 n 次 |
X{n,} | X,至少 n 次 |
X{n,m} | X,至少 n 次,但是不超過m 次 |
Reluctant 數量詞 | |
X?? | X,一次或一次也沒有 |
X*? | X,零次或多次 |
X+? | X,一次或多次 |
X{n}? | X,恰好 n 次 |
X{n,}? | X,至少 n 次 |
X{n,m}? | X,至少 n 次,但是不超過m 次 |
Possessive 數量詞 | |
X?+ | X,一次或一次也沒有 |
X*+ | X,零次或多次 |
X++ | X,一次或多次 |
X{n}+ | X,恰好 n 次 |
X{n,}+ | X,至少 n 次 |
X{n,m}+ | X,至少 n 次,但是不超過m 次 |
Logical 運算符 | |
XY | X 後跟 Y |
X|Y | X 或 Y |
(X) | X,作爲捕獲組 |
Back 引用 | |
\n | 任何匹配的 nth捕獲組 |
引用 | |
\ | Nothing,但是引用以下字符 |
\Q | Nothing,但是引用所有字符,直到 \E |
\E | Nothing,但是結束從 \Q 開始的引用 |
三、正則表達式的功能說明已經代碼演示
1、四大功能說明
◆匹配:String類中的boolean
matches(String regex)方法。用規則匹配整個字符串,只要有一處不符合規則,就匹配結束,返回false。
◆切割:String類中的String[]split(String
regex)方法。
◆替換: String
replaceAll(String regex,String replacement)方法。
◆獲取:將字符串中的符合規則的子串取出。
操作步驟:
1)將正則表達式封裝成對象。(用Pattern中的靜態方法compile()封裝成對象)
2)讓正則對象和要操作的字符串相關聯。(用Pattern中matcher()匹配,並且返回匹配引擎)
3)關聯後,獲取正則匹配引擎。(獲得匹配引擎)
4)通過引擎對符合規則的子串進行操作,比如取出。(利用匹配引擎的find(),和group進行查找和獲得結果)
◆根據規則匹配郵箱:
package regular;
public class RegularText3 {
public static void main(String[] args) {
// 給你一個郵箱
String emai = "[email protected]";
// 創建規則並且傳入匹配再打印。規則解析:
// 任意4到16字母數字或者下劃線,必須還有@,一位或者多位字母一組或者多組:(。字母一組或者多組任意字母)
System.out.println(emai.matches("\\w{4,16}@[a-zA-Z]+(\\.[a-zA-Z]+)+"));
}
}
打印結果:
◆去除疊詞的操作:
package regular;
/*
需求:去掉疊詞和.
*/
public class Regulartext {
public static void main(String[] args)
{
// 給定一個字符串
String str = "我我。。。我。。。我好。。。想。。。想想。。好想。。。。。陳。。穎穎。。。穎異。。啊啊啊";
test_1(str);
}
public static void test_1(String str)
{
// 創建規則
String reg = "。+";
// 把所有的.去掉
str=str.replaceAll(reg, "");
// 打印去掉後的結果
System.out.println(str);
// 將疊詞替換成不是疊詞
str=str.replaceAll("(.)\\1+","$1");
// 打印結果
System.out.println(str);
}
}
打印結果:
◆給定一段雜亂IP對其進行處理,這裏將用到正則表達式的替換功能:
package regular;
import java.util.Arrays;
/*
需求:將ip地址進行地址段順序的排序。
思路:還按照字符串自然順序,只要讓它們每一段都是3位即可。
1,按照每一段需要的最多的0進行補齊,那麼每一段就會至少保證有3位。
2,將每一段只保留3位。這樣,所有的ip地址都是每一段3位。
*/
public class Regulartext2 {
public static void main(String[] args) {
// 給出幾段雜亂的IP
String ip= "192.068.0.101 18.5.40.1 15.88.205.10";
// 要進行排序就要進行比較,但是位數不想等,所以先爲小段數字前面加兩個0
ip = ip.replaceAll("(\\d+)", "00$1");
// 打印加0後的結果
System.out.println(ip);
// 然後讓沒小段保留三位數
ip = ip.replaceAll("0*(\\d{3})", "$1");
// 打印保留三位的結果
System.out.println(ip);
// 按照一個或者多個空格切割
String s[]=ip.split(" +");
// 數組的自然排序
Arrays.sort(s);
// 打印排序後的結果
System.out.println(s[0]+" "+s[1]+" "+s[2]);
// 去掉前面多餘的0
System.out.println(s[0].replaceAll("0*(\\d+)", "$1")+" "+s[1].replaceAll("0*(\\d+)", "$1")
+" "+s[2].replaceAll("0*(\\d+)", "$1"));
}
}
打印結果:
◆獲取功能演示:
package regular;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegularText4 {
public static void main(String[] args) {
// 給定一個字符串
String str ="wu jian chen aa ying yi qqq bbb a";
// 建立規則,當爲:邊界、4個字母、邊界,就符合規則
String reg ="\\b[a-zA-Z]{4}\\b";
// 封裝成對象
Pattern par = Pattern.compile(reg);
// 關聯字符串,獲得匹配引擎
Matcher ma = par.matcher(str);
// 開始查找符合規則的數據
while(ma.find())
{
// 獲得查找結果並且打印
System.out.println(ma.group());
}
}
}
打印結果:
四、綜合例題(網絡爬蟲)演示
這裏以爬人人網的某些數據爲例子
package regular;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/*
需求:自己寫連接去網絡上找相應規則的數據,這裏以人人網的網頁爲例
*/
public class Crawler {
public static void main(String[] args) throws Exception {
// 解析地址,封裝對象,建立連接所需要的資源
URL url =new URL("http://tw.people.com.cn/n/2015/0801/c104510-27396313.html");
// 開始連接,並且獲取連接對象
URLConnection uc=url.openConnection();
// 對過連接的對象可以獲取輸入流
BufferedReader bf = new BufferedReader(new InputStreamReader(uc.getInputStream()));
// 封裝規則爲對象,
Pattern pat = Pattern.compile("0\\d{3}.\\d+");
String line =null;
// 讀取網頁信息
while((line=bf.readLine())!=null)
{
// 獲取匹配引擎,關聯字符串
Matcher mat =pat.matcher(line);
// 開始尋找
while(mat.find())
{
// 顯示查找結果
System.out.println(mat.group());
}
}
}
}
結果爲:
正則表達式介紹完畢,感謝瀏覽!