00 09Java高級之正則表達式

1 認識正則表達式

通過之前一系列分析可以發現,String是一個非常萬能的類型,因爲String不僅支持各種字符串的處理操作,也支持有向各個數據類型轉換的功能,所以在項目的開發之中,只要是用戶輸入的信息基本上都用String表示。於是在向其他數據類型轉換的時候,爲了保證轉換的正確性,往往要對其進行一些複雜的驗證處理,那麼這種情況下,如果只是單純的依靠String類中的方法是非常麻煩的。

現在假設有一個字符串要求你判斷字符串是否由數字所組成,如果由數字所組成則將其變爲數字並進行乘法計算。
範例:

package cn.victor.demo;

import java.text.NumberFormat;
import java.text.ParseException;

public class DateDemo {

	public static void main(String[] args) throws ParseException {
		String str = "123";
		if(isNumber(str)) {
			long n = Integer.parseInt(str);
			System.out.println(n * 2);
		}
		
	}
	
	public static boolean isNumber(String str) {
		char[] chars = str.toCharArray();
		for(int i = 0; i < chars.length; i++) {
			if( chars[i] < '0' || chars[i] > '9' ) {
				return false;
			}
		}
		
		return true;
	}
}


實際上這種驗證的功能是非常簡單的,但是這如此簡單的功能卻需要開發者編寫大量的程序邏輯代碼,那麼如果是更加複雜的驗證呢?那麼在這樣的情況下,對於驗證來講最好的做法就是利用正則表達式來完成。
範例:使用正則表達式實現同樣的效果

package cn.victor.demo;

import java.text.NumberFormat;
import java.text.ParseException;

public class DateDemo {

	public static void main(String[] args) throws ParseException {
		String str = "123";
		if(str.matches("\\d+")) {
			long n = Integer.parseInt(str);
			System.out.println(n * 2);
		}
		
	}
}


正則表達式最早是從Perl語言裏面發展而來的,而後在JDK 1.4以前如果需要使用到正則表達式的相關定義,則需要單獨引入其它jar文件,但是從JDK 1.4之後,正則已經默認被JDK所支持,並且提供有java.util.regex開發包,同時針對於String類也進行了一些修改,使其有方法直接支持正則處理。

使用正則最大的特點在於方便進行驗證處理,以及方便進行復雜字符串的修改處理。

2 常用正則標記

如果要想進行正則的處理操作,那麼就首先需要對常用的正則標記有所掌握,從JDK 1.4開始提供有java.util.regex開發包,這個包裏面提供有一個Pattern程序類,在這個程序類裏面定義有所有支持的正則標記。
(1)【數量:單個】字符匹配
|——任意字符:表示由任意字符組成
|——\\:匹配“\”;
|——\n:匹配換行;
|——\t:匹配製表符;
(2)【數量:單個】字符集(可以從裏面任選一個字符)
|——[abc]:表示可能是字母a、b、c中的任意一個字符;
|——[\^abc]:表示不是字母a、b、c中的任意一個;
|——[a-zA-Z]:表示由一個任意字母所組成,不區分大小寫;
|——[0-9]:表示由一位數字組成。
(3)【數量:單個】簡化的字符集
|——.:表示任意的字符;
|——\d:等價於範圍[0-9]
|——\D:等價於範圍[^0-9]
|——\s:匹配任意的一位空格,可能是空格、換行、製表符;
|——\S:匹配任意的非空格數據;
|——\w:匹配字母、數字、下劃線,等價於[a-zA-Z_0-9]
|——\W:匹配非字母、數字、下劃線,等價於[^a-zA-Z_0-9]
(4)邊界匹配
|——^:匹配邊界開始;
|——$:匹配邊界結束;
(5)數量表示,默認情況下只有添加上了數量單位纔可以匹配多位字符。
|——表達式?:該正則可以出現0次或1次。
|——表達式*:該正則可以出現0次、1次或多次;
|——表達式+:該正則可以出現1次或多次;
|——表達式{n}:表達式的長度正好爲n次;
|——表達式{n,}:表達式的長度爲n次以上;
|——表達式{n,m}:表達式的長度爲n~m次;
(6)邏輯表達式:可以連接多個正則:
|——表達式X表達式Y:X表達式之後緊跟上Y表達式。
|——表達式X|表達式Y:有一個表達式滿足即可。
|——(表達式):爲表達式設置一個整體描述,可以爲整個描述設置數量單位。

3 String類對正則的支持

在進行正則表達式大部分處理情況下都會基於String類來完成,並且在String類裏面提供有如下操作方法:

No. 方法名稱 類型 描述
01 public boolean matches​(String regex) 普通 將指定字符串進行正則判斷
02 public String replaceAll​(String regex, String replacement) 普通 替換全部
03 public String replace​(char oldChar, char newChar) 普通 替換首個
04 public String[] split​(String regex) 普通 正則拆分
05 public String[] split​(String regex, int limit) 普通 正則拆分

下面通過一些具體得範例來對正則的使用進行說明。
範例:實現字符串的替換(刪除非字母與數字)

package cn.victor.demo;

public class DateDemo {

	public static void main(String[] args) {
		String str = "328d$%$(fdf32(*&c34f34c24334gfg34c324c&crfgdsfg^%^$324csdsd##";
		String replstr = str.replaceAll("[^a-zA-Z0-9]", "");
		System.out.println(replstr);
		
	}
}


範例:實現字符串的拆分(按數字拆分)

package cn.victor.demo;

public class DateDemo {

	public static void main(String[] args) {
		String str = "328d$%$(fdf32(*&c34f34c24334gfg34c324c&crfgdsfg^%^$324csdsd##";
		String replstr[] = str.split("\\d+");
		for(int i = 0; i < replstr.length; i++) {
			System.out.println(replstr[i]);
		}
		
	}
}


在正則處理的時候對於拆分與替換的操作相對容易一些,但是比較麻煩的是數據驗證部分。
範例:判斷一個數據是否爲小數,如果是小數則將其變爲double類型

package cn.victor.demo;

public class DateDemo {

	public static void main(String[] args) {
		String str = "23";
		System.out.println(str.matches("\\d+(\\.\\d+)?"));
	}
}


範例:判斷一個字符串是否由日期組成,如果是由日期所組成則將其轉爲Date類型

package cn.victor.demo;

import java.text.ParseException;
import java.text.SimpleDateFormat;

public class DateDemo {

	public static void main(String[] args) throws ParseException {
		String str = "1999-08-21";
		if(str.matches("\\d{4}-\\d{2}-\\d{2}"))
		{
			System.out.println(new SimpleDateFormat("yyyy-MM-dd").parse(str));
		}
	}
}


正則不能判斷具體含義,只能對格式進行判斷處理。
範例:判斷給定的電話號碼是否正確?
(1)電話號碼:51283346,\\d{7,8}
(2)電話號碼:01051283346,(\\d{3,4})?\\d{7,8}
(3)電話號碼:(010)-51283346,((\\d{3,4})|(\\(\\d{3,4}\\))-)?\\d{7,8}

package cn.victor.demo;

import java.text.ParseException;
import java.text.SimpleDateFormat;

public class DateDemo {

	public static void main(String[] args) throws ParseException {
		String str = "(010)-5128331";
		System.out.println(str.matches("((\\d{3,4})|(\\(\\d{3,4}\\)))?-?\\d{7,8}"));
	}
}


既然已經可以使用正則進行驗證了,那麼下面就可以利用其來實現一個email地址格式的驗證。
範例:驗證email格式
(1)email的用戶名可以由字母數字_ 所組成;
(2)email的域名可以由字母數字_- 所組成;
(3)域名的後綴必須是:.cn.com.net.com.cn.gov

package cn.victor.demo;

public class DateDemo {

	public static void main(String[] args) {
		String str = "[email protected]";
		System.out.println(str.matches("[^_]\\w+@[\\w-]+\\.(com|cn|com.cn|edu|gov)"));
	}
}


現在這幾種正則的匹配處理操作是最常用的幾種處理形式。

4 java.util.regex包支持

雖然在大部分情況下都可以利用String類實現正則的操作,但是也有一些情況下需要使用到java.util.regex開發包中提供的正則處理類,在這個包裏面一共定義有兩個類:Pattren(正則表達式編譯)、Matcher(匹配)。
1、Pattern類
(1)Pattern類提供有正則表達式的編譯處理支持:public static Pattern compile​(String regex)
(2)同時也提供有字符串的拆分操作支持:public String[] split​(CharSequence input)

package cn.victor.demo;

import java.util.regex.Pattern;

public class DateDemo {

	public static void main(String[] args) {
		String str = "1s2s3s4";
		Pattern pat = Pattern.compile("s");
		String[] resultset = pat.split(str);
		for(int i = 0; i < resultset.length; i++) {
			System.out.println(resultset[i]);
		}
	}
}


2、Matcher類,實現了正則匹配的處理類,這個類的對象實例化依靠Pattern類完成。
(1)Pattern類提供的方法:public Matcher matcher​(CharSequence input)
當獲取了Matcher類的對象之後就可以利用該類中的方法進行如下操作:
(1)正則匹配:public boolean matches()

package cn.victor.demo;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class DateDemo {

	public static void main(String[] args) {
		String str = "123";
		Pattern pat = Pattern.compile("\\d+");
		Matcher mac = pat.matcher(str);
		System.out.println(mac.matches());
	}
}


(2)字符串替換:public String replaceAll​(String replacement)

package cn.victor.demo;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class DateDemo {

	public static void main(String[] args) {
		String str = "1s2s3";
		Pattern pat = Pattern.compile("s");
		Matcher mac = pat.matcher(str);
		System.out.println(mac.replaceAll(""));
	}
}


如果純粹的是以拆分、替換、匹配三種操作爲例,根本用不到java.util.regex開發包,只依靠String類就都可以實現了。但是Matcher類裏面提供有一種分組的功能,而這種分組的功能是String不具備的。

package cn.victor.demo;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class DateDemo {

	public static void main(String[] args) {
		String str = "select * from table values(#{dept},#{no},#{name})";
		Pattern pat = Pattern.compile("#\\{\\w+\\}");
		Matcher mac = pat.matcher(str);
		while(mac.find()) {
			System.out.println(mac.group(0).replaceAll("\\W+", ""));
		}
	}
}


java.util.regex開發包,如果不是進行一些更爲複雜的正則處理是很難使用到的,而String類所提供的功能只適合於正則的基本操作。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章