使用java正則表達式的正確姿勢
文章目錄
一、用途
- 用於字符串處理
- 字符串匹配
- 字符串查找
- 字符串替換
- 例子
- IP地址是否正確
- 從網頁中揪出email地址
- 從網頁中揪出鏈接等
- 使用的類
- java.lang.String
- java.util.regex.Pattern
- java.util.regex.Matcher
二、. * + ? 表示什麼意思?
- *表示是一個字符
- X*表示X出現0個或多個
- X+表示出現1個或多個
- X?表示X出現0個或1個
- X{n}表示X出現n次
- X{n,}X最少出現n次,最多出現次數不限制
- X{n,m}X出現至少n次,不超過m次
- {}表示對字符出現次數的限制
- [-]表示限制字符範圍
10.[a-z]表示字符範圍只能是a-z
示例代碼:
//初步認識. * + ? {} []
p("a".matches("."));//true
p("aa".matches("aa"));//true
p("aaaa".matches("a*"));//true
p("aaaa".matches("a+"));//true
p("".matches("a*"));//true
p("aaaa".matches("a?"));//false
p("".matches("a?"));//true
p("a".matches("a?"));//true
p("21234567898".matches("\\d{3,100}"));//true
p("192.168.0.aaa".matches("\\d(1,3)\\.\\d(1,3)\\.\\d(1,3)\\.\\d(1,3)"));//false
p("192".matches("[0-2][0-9][0-9]"));//true
private static void p(Object o){
System.out.println(o);
}
三、[]表示什麼意思?(控制範圍)
- []表示匹配[]內其中一個字符
- ^表示取反
- -表示範圍
- |表示或者 &&表示並且
示例代碼:
public static void main(String[] args) {
//範圍
p("a".matches("[abc]"));//匹配abc其中的一個字符 true
p("a".matches("^abc"));//匹配abc之外的字符 false
//匹配a-z或者A-Z之間的字符 3種寫法
p("A".matches("[a-zA-Z]"));//true
p("A".matches("[a-z]|[A-Z]"));//true
p("A".matches("[a-z[A-Z]]"));//true
p("R".matches("[A-Z&&[RFG]]"));//A-Z之間並且是RFG三者之一 true
}
private static void p(Object o){
System.out.println(o);
}
四、常用的"\字母"表示什麼意思?
- \d表示0-9之間的數字 [0-9]
- \D表示除0-9之外的字符 [^0-9]
- \s表示一個空白字符[ \t\n\x0b\f\r] 包含空格tab鍵等
- \S表示不包含空白字符[^\s]
- \w表示包含構成英文單詞的字符[a-zA-Z_0-9]
- \W表示不包含英文單詞的字符[^\w]
示例:
//認識\s \w \d \
p(" \n\r\t".matches("\\s{4}"));//true
p(" ".matches("\\S"));//false
p("a_0".matches("\\w{3}"));//true
p("abc888&^%".matches("[a-z]{1,3}\\d+[&^%]+"));//true
p("\\".matches("\\\\"));// java比較反斜槓 true
private static void p(Object o){
System.out.println(o);
}
五、邊界
^ 表示起始位置
$ 表示結束位置
\b表示一個單詞的邊界(邊界指的是空格、換行、空白字符、tab鍵等)
示例:
//邊界
p("hello sir".matches("^h.*"));//h開頭後面跟0個或者多個字符 true
p("hello sir".matches(".*ir$"));//ir結尾前面有0個或者多個字符 true
p("hello sir".matches("^h[a-z]{1,3}o\\b.*"));//h開頭,o後面是否包含單詞邊界 true
p("hellosir".matches("^h[a-z]{1,3}o\\b.*"));//h開頭,o後面是否包含單詞邊界 false
private static void p(Object o){
System.out.println(o);
}
六、matches、find、lookingAt
matches匹配整個字符串
find找子串
lookAt從開始位置找
示例代碼:
Pattern p = Pattern.compile("\\d{3,5}");//全部爲數字,長度爲3-5
String s = "123-23234-234-00";
Matcher m = p.matcher(s);
p(m.matches());//false
m.reset();//matches和find一起使用會出現問題,一般要加reset,否則輸出結果會有出入
//find 依次查找子串
p(m.find());//true
//輸出找到子串以後的開始位置和結束位置(前提是必須能找到這子串,否則會報錯)
p(m.start() + "-" + m.end());//輸出0-3
p(m.find());//true
p(m.start() + "-" + m.end());//輸出4-9
p(m.find());//true
p(m.start() + "-" + m.end());//輸出10-13
p(m.find());//false
//lookingAt從開始位置找,每次從開頭開始找
p(m.lookingAt());//true
p(m.lookingAt());//true
p(m.lookingAt());//true
p(m.lookingAt());//true
}
private static void p(Object o){
System.out.println(o);
}
七、replacement字符串替換
示例代碼:
//字符串替換replacement
Pattern pattern = Pattern.compile("java",Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher("java JAVA JAva JaVa JAvA iloveJava you hate java");
//把字符串中所有的java(忽略大小寫),全部替換成大寫的JAVA
p(matcher.replaceAll("JAVA"));
private static void p(Object o){
System.out.println(o);
}
輸出結果如下:
示例代碼2:
//字符串替換replacement
Pattern pattern = Pattern.compile("java",Pattern.CASE_INSENSITIVE);//忽略大小寫
Matcher matcher = pattern.matcher("java JAVA JAva JaVa JAvA iloveJava you hate java the end");
//要求把找到的第一個java字符串編程大寫,找到的第二個變成小寫,依次類推
StringBuffer buffer = new StringBuffer();
int i = 0;
while (matcher.find()){
i++;
if(i % 2 == 0){
matcher.appendReplacement(buffer,"java");
}else {
matcher.appendReplacement(buffer,"JAVA");
}
}
matcher.appendTail(buffer);//加上尾巴
p(buffer);
}
private static void p(Object o){
System.out.println(o);
}
輸出結果:
八、group分組
如何判斷是第幾組,數小括號就行
作用:抓取字符串中的部分內容
示例代碼:
//分組
Pattern pattern = Pattern.compile("(\\d{3,5})([a-z]{2})");//匹配3-5位的數字,兩個字母
String s = "123aa-345345bb-234cc-00";
Matcher matcher = pattern.matcher(s);
while (matcher.find()){
//只輸出3-5位的數字也就是第一組
p(matcher.group(1));
//只輸出兩位字母也就是第二組
// p(matcher.group(2));
private static void p(Object o){
System.out.println(o);
}
輸出結果:
如果group傳入的是2,則輸出如下:
如果group什麼都不傳,則輸出結果如下:
九、讀取本地網頁中的email地址
示例代碼:
public class EmailSpider {
public static void main(String[] args) {
try {
BufferedReader br = new BufferedReader(new FileReader("E:\\留下你的電子郵箱地址,我們來寫Email吧。.html"));
String line = "";
while ((line = br.readLine()) != null){
//判斷有沒有讀到結尾
parse(line);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private static void parse(String line) {
Pattern pattern = Pattern.compile("^\\s*\\w+(?:\\.{0,1}[\\w-]+)*@[a-zA-Z0-9]+(?:[-.][a-zA-Z0-9]+)*\\.[a-zA-Z]+\\s*$");
Matcher matcher = pattern.matcher(line);
while (matcher.find()){
System.out.println(matcher.group());
}
}
}
十、其他知識
向前引用:
示例代碼:
//向前引用
Pattern pattern = Pattern.compile("(\\d\\d)\\1");
// \\1指的是後面找到的結果必須和第一個組捕捉的字符串一樣
String s = "1214";//false
// String s = "1212";//true
Matcher matcher = pattern.matcher(s);
System.out.println(matcher.matches());
忽略大小寫或者其他規則可以用下面這種寫法:
//忽略大小寫
//第一種寫法
Pattern pattern = Pattern.compile("java",Pattern.CASE_INSENSITIVE);
//第二種寫法
p("java".matches("(?i)(java)"));