Java高階進修之正則表示式
正則表示式
1 正則表示式
正則表示式:其實一種規則,有自己特殊的應用,其作用就是針對於字串進行操作。
正則:就是用於操作字串的規則,其中這些規則使用了一些字元表示。
需求:只能輸入數字
public class Demo2{
public static void main(String[] args) {
//只能輸入數字
String str = "124354232";
char[] arr = str.toCharArray ();
boolean flag = true;
for(int i = 0 ; i< arr.length ; i++){
if(!(arr[i]>=48&&arr[i]<=57)){
flag = false;
}
}
System.out.println(flag?"輸入正確":"輸出只能是數字");
}
}
使用正則表示式:
public class Demo2{
public static void main(String[] args) {
//只能輸入數字
String str = "12435423a2";
boolean flag = str.matches("[0-9]+");
System.out.println(flag?"輸入正確":"只能輸入數字");
}
}
2 正則表示式的符號
預定義字元類
.
任何字元(與行結束符可能匹配也可能不匹配)
\d
數字:[0-9]
\D
非數字: [^0-9]
\s
空白字元:[ \t\n\x0B\f\r]
\S
非空白字元:[^\s]
\w
單詞字元:[a-zA-Z_0-9]
\W
非單詞字元:[^\w]
System.out.println ("a".matches("."));
System.out.println("1".matches("\\d"));
System.out.println("%".matches("\\D"));
System.out.println("\r".matches("\\s"));
System.out.println("^".matches("\\S"));
System.out.println("a".matches("\\w"));
Greedy 數量詞
X?
X,一次或一次也沒有
X*
X,零次或多次
X+
X,一次或多次
X{n}
X,恰好n次
X{n,}
X,至少n次
X{n,m}
X,至少n次,但是不超過m次
System.out.println( "a".matches(".") );
System.out.println( "a".matches("a") );
System.out.println("a".matches("a?") );
System.out.println( "aaa".matches("a*") );
System.out.println( "".matches("a+") );
System.out.println( "aaaaa".matches("a{5}") );
System.out.println( "aaaaaaaaa".matches("a{5,8}") );
System.out.println( "aaa".matches("a{5,}") );
System.out.println( "aaaaab".matches("a{5,}") );
範圍表示
[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](減去)
System.out.println( "a".matches("[a]") );
System.out.println( "aa".matches("[a]+") );
System.out.println( "abc".matches("[abc]{3,}") );
System.out.println( "abc".matches("[abc]+") );
System.out.println( "dshfshfu1".matches("[^abc]+") );
System.out.println( "abcdsaA".matches("[a-z]{5,}") );
System.out.println( "abcdsaA12".matches("[a-zA-Z]{5,}") );
System.out.println( "abcdsaA12".matches("[a-zA-Z0-9]{5,}") );
System.out.println( "abdxyz".matches("[a-c[x-z]]+"));
System.out.println( "bcbcbc".matches("[a-z&&[b-c]]{5,}"));
System.out.println( "tretrt".matches("[a-z&&[^b-c]]{5,}"));
^
行的開頭
$
行的結尾
\b
單詞邊界
\B
非單詞邊界
\A
輸入的開頭
\G
上一個匹配的結尾
\Z
輸入的結尾,僅用於最後的結束符(如果有的話)
\z
輸入的結尾
System.out.println("45678".matches("^[^0]\\d+"));
System.out.println("demo.java".matches("\\w+\\.java$"));
3 匹配功能
需求:校驗QQ號,要求:必須是5~15位數字,0不能開頭。沒有正則表示式之前
public static void checkQQ(String qq){
int len = qq.length();
if(len>=5 && len <=15) {
if(!qq.startsWith("0")) {
try {
long l = Long.parseLong(qq);
System.out.println("qq:"+l);
}
catch (NumberFormatException e) {
System.out.println("出現非法字元");
}
}
else
System.out.println("不可以0開頭");
}
else
System.out.println("QQ號長度錯誤");
}
有了正則表示式之後:
[1-9][0-9]{4,14}
[1-9]表示是第一位數字是會出現1-9範圍之間的其中一個,下來的數字範圍會出現在0-9之間,至少出現4次,最多出現14次。
public static void checkQQ2(){
String qq = "12345";
String reg = "[1-9][0-9]{4,14}";
boolean b = qq.matches(reg);
System.out.println("b="+b);
}
需求:匹配是否為一個合法的手機號碼。
public static void checkTel() {
String tel = "25800001111";
String reg = "1[35]\\d{9}";//在字串中,定義正則出現\ 要一對出現。
boolean b= tel.matches(reg);
System.out.println(tel+":"+b);
}
4 切割功能
需求1:根據空格對一段字串進行切割。
public static void splitDemo() {
String str = "aa.bb.cc";
str = "-1 99 4 23";
String[] arr = str.split(" +");
for(String s : arr) {
System.out.println(s);
}
}
需求2 :根據重疊詞進行切割。
public static void splitDemo2(){
String str = "sdqqfgkkkhjppppkl";
String[] arr = str.split("(.)\\1+");
for(String s : arr) {
System.out.println(s);
}
}
注意:為了提高規則複用,用()進行封裝,每一個括號都有一個編號,從1開始,為了複用這個規則。可以通過編號來完成該規則的呼叫。需要對編號數字進行轉義。\1就代表獲取1組規則。
5 替換功能
需求:把字串中的重疊字替換成單個單詞。
public static void replaceDemo(){
String str = "sdaaafghcccjkqqqqqql";
String s = str.replaceAll("(.)\\1+","$1");//$ 可以獲取到該方法中正則實際引數中的某一個存在的組 $組編號即可。
System.out.println(str+":"+s);
String nums = "wser127372tyuiopd6226178909876789fghjk";
String s1 = nums.replaceAll("\\d+","*");
System.out.println(nums+":"+s1);
}
6 獲取
獲取需要使用到正則的兩個物件:使用的是用正則物件Pattern
和匹配器Matcher
。
範例:
Pattern p = Pattern.compile("a*b");
Matcher m = p.matcher("aaaaab");
boolean b = m.matches();
步驟:
- 先將正則表示式編譯成正則物件。使用的是Pattern類一個靜態的方法。compile(regex);
- 讓正則物件和要操作的字串相關聯,通過matcher方法完成,並返回匹配器物件。
- 通過匹配器物件的方法將正則模式作用到字串上對字串進行鍼對性的功能操作
需求:獲取由3個字母組成的單詞。
public static void getDemo() {
String str = "da jia zhu yi le,ming tian bu fang jia,xie xie!";
//想要獲取由3個字母組成的單詞。
//剛才的功能返回的都是一個結果,只有split返回的是陣列,但是它是把規則作為分隔符,不會獲取符合規則的內容。
//這時我們要用到一些正則物件。
String reg = "\\b[a-z]{3}\\b";
Pattern p = Pattern.compile(reg);
Matcher m = p.matcher(str);
while(m.find()) {
System.out.println(m.start()+"...."+m.end());
System.out.println("sub:"+str.substring(m.start(),m.end()));
System.out.println(m.group());
}
// System.out.println(m.find());//將規則對字串進行匹配查詢。
// System.out.println(m.find());//將規則對字串進行匹配查詢。
// System.out.println(m.group());//在使用group方法之前,必須要先找,找到了才可以取。
}
校驗郵件
public static void checkMail(){
String mail = "[email protected]";
mail = "[email protected]";
String reg = "[a-zA-Z_0-9][email protected][a-zA-Z0-9]+(\\.[a-zA-Z]+)+";
reg = "\\[email protected]\\w+(\\.\\w+)+";//簡化的規則。籠統的匹配。
boolean b = mail.matches(reg);
System.out.println(mail+":"+b);
}
網路爬蟲
class GetMailList {
public static void main(String[] args) throws Exception{
String reg = "\\[email protected][a-zA-Z]+(\\.[a-zA-Z]+)+";
getMailsByWeb(reg);
}
public static void getMailsByWeb(String regex)throws Exception{
URL url = new URL("http://localhost:8080/myweb/mail.html");
URLConnection conn = url.openConnection();
BufferedReader bufIn = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line = null;
Pattern p = Pattern.compile(regex);
while((line=bufIn.readLine())!=null){
//System.out.println(line);
Matcher m = p.matcher(line);
while(m.find()){
System.out.println(m.group());
}
}
bufIn.close();
}
public static void getMails(String regex)throws Exception{
BufferedReader bufr =
new BufferedReader(new FileReader("mail.txt"));
String line = null;
Pattern p = Pattern.compile(regex);
while((line=bufr.readLine())!=null){
//System.out.println(line);
Matcher m = p.matcher(line);
while(m.find()){
System.out.println(m.group());
}
}
bufr.close();
}
}