14 Regex功能小結
正則表示式
視訊1:01-正則表示式-概述&常見功能
正則表示式:專門用於操作字串的技術。而且可以簡化程式碼,用於對字串進行復雜操作。
通過一些符號的形式來簡化程式碼的書寫,其實底層對應的還是程式碼。
弊端:符號太多,閱讀性差。
所以,學習正則,先要學習一些符號。
正則對字串大的常見操作功能:
1. 匹配
2. 切割
3. 替換
4. 獲取
例子:
1. 對QQ號進行校驗
2. 要求:5-15位,0不可以開頭,必須都是數字。
public boolean matches
String qq=”1235343k343”;
booleanb=qq.matches(“[1-9][0-9]{4-14}”);
System.out.println(qq+”:”+b);
視訊2:02-正則表示式-符號
遇到反斜槓要輸入兩次反斜槓
x |
字元 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 |
輸入的結尾 |
||||
Greedy 數量詞 |
|||||
X? |
X,一次或一次也沒有 |
||||
X* |
X,零次或多次 |
||||
X+ |
X,一次或多次 |
||||
X{n} |
X,恰好 n 次 |
||||
X{n,} |
X,至少 n 次 |
||||
X{n,m} |
X,至少 n 次,但是不超過 m 次 |
正則對字串大的常見操作功能:
匹配
使用String類中的matches方法;
StringphoneNumber=”18212343217”;
Stringregex=”1[358]\\d{9}”;
booleanb= phoneNumber.matches(regex);
System.out.println(phoneNumber+”:”+b);
切割
public String[] split(String regex,int limit)
根據匹配給定的正則表示式來拆分此字串。
//例一
String str=”zhangsan lisi wangwu”;
String regex=” +”;
String[] strs=str.split(regex);
for(String s: strs)
{System.out.println(“-”+s+”-”);}
//例二
tring str=”zhangsan.lisi.wangwu”;
String regex=”\\.”; //這裡只打一個.是沒用的,因為.在正則裡面代表任意字元
String strs=str.split(regex);
for(String s: strs)
{System.out.println(“-”+s+”-”);}
//例三,連續重複的疊詞進行分割
//正則規則的複用,想複用,先封裝,正則封裝用()完成,封裝完成後有編號,從1開始。正則中被()封裝的稱之為組,直接通過編號就可以呼叫對應的組。呼叫方式就是寫已有的組的編號前加上\\ 如:\\1,在使用已有第一組的內容。原則:先有組,才可以使用對應的編號呼叫。
(A)(B)(C)(D)\\1\\3\\2\\4 表示:ABCDACBD
((A)(B(C)))這個有多少組? 數左括號,按左括號編號
1組 |
((A)(B(C))) |
|
2組 |
A |
|
3組 |
(B(C)) |
|
4組 |
(C) |
|
沒有打左括號,整個就是一個組,編號位0 |
|
String str=”ert###yuixkkkkcvbn”;
String regex=”(.)\\1+”;
String strs=str.split(regex);
for(String s: strs)
{System.out.println(“-”+s+”-”);}
替換
public String replaceAll(String regex,String replacement)
使用給定的 replacement 替換此字串所有匹配給定的正則表示式的子字串。
public String replaceFirst(String regex,String replacement)
使用給定的 replacement 替換此字串匹配給定的正則表示式的第一個子字串。
//public String replace(char oldChar, char newChar)
//public String replace(CharSequence target,CharSequence replacement)
//例一:疊詞用一個#替換
String str=”wert####[email protected]@@@@@@@dfgh”;
Str=str.replaceAll(”(.)\\1+”,”#”);
System.out.println(str);
//例二:疊詞用疊詞第一個字元替換
String str=”wert####yuios#####dfgh”;
Str=str.replaceAll(”(.)\\1+”,”$1”);//在引數列表中,其他引數要使用前一個引數中的規則的組,需要用$加組編號,例如$1
System.out.println(str);
//例三:號碼中間的四位數字用****替換
String str=”18612345678”;
//方法:分組,將前三位數字分組為1,後四位數字分組為2
Str=str.replaceAll(”(\\d{3})\\d{4}(\\d{4})”,”$1****$2”);
System.out.println(str);
//例四:論壇遮蔽QQ號,電話號碼,銀行卡號等 但類似這樣的:QQ:衣爾散思。。。就沒辦法了
String str=”芳齡:20,QQ號:99999999999fghjkl87772374232742739342rtewqsaf”; //連續5個以上數字就用***替換
Str=str.replaceAll(”\\d{5,} ”,”***”);
System.out.println(str);
獲取
//以上三個功能內部都是Pattern正則表示式物件。現在需要其他功能時,字串String類中沒有對應的方法,只能找Pattern物件(檢視API);
/*
Pattern物件的使用原理:
1. 將正則表示式字串編譯成正則物件pattern
2. 通過pattern物件獲取Matcher物件(匹配器物件)
3. 通過匹配器物件對字串進行規則的匹配,結果都在匹配器中
4. 通過匹配器物件的功能獲取結果。
5. 範例程式碼:
Patternp=Pattern.compile(”a*b”);
Matcherm=p.matcher(“aaaaab”);
Booleanb=m.maches();
在僅使用一次正則表示式時,可以方便地通過此類定義matches 方法。此方法編譯表示式並在單個呼叫中將輸入序列與其匹配。語句
boolean b =Pattern.matches("a*b", "aaaaab");
等效於上面的三個語句,儘管對於重複的匹配而言它效率不高,因為它不允許重用已編譯的模式。
*/
Stringstr="da jia zhu yi le, ming tian fang jiale!";
String regex="\\b[a-zA-Z]{3}\\b"; //取出由3個字母組成的單詞,\\b表示單詞邊界,否則ming的前三個字母組成的min也將被輸出
Pattern p=Pattern.compile(regex);
Matcher m=p.matcher(str);
booleanb=m.matches();
System.out.println(b);
while(m.find())
{
System.out.println(m.group()+".."+ m.start()+"--"+m.end());
System.out.println(str.substring(m.start(),m.end()));
}
import java.lang.reflect.Array;
importjava.util.Arrays;
publicclass ReduplicationDemo1
{
publicstaticvoid main(String[] args)
{
test1();
test2();
test3();
}
privatestaticvoid test3()
{
/*
* 案例三:對郵箱地址進行校驗
*/
String mail="[email protected]";
//精準校驗
String regex="[a-zA-Z0-9_][email protected][a-zA-Z0-9-]+(\\.[a-zA-Z]{2,3}){1,3}";
booleanb=mail.matches(regex);
System.out.println(mail+":"+b);
//籠統校驗
regex="\\[email protected]\\W+(\\.\\w+)+";
}
privatestaticvoid test2()
{
/*
*案例二:
*"23.12.10.5 192.168.100.322 3.3.3.3 10.10.10.10 "
*要求將這些ip按照順序排序。
*
*思路:
*1.將ip通過空格切割
*2.對ip進行排序,通過字串字典順序排序,這個順序是錯的
* 原因:每個ip有四段,每一段最多三位,應該按照位數比較才是對的,否則192 與 3 就是百位與個位的數相比
* 所以應該每一段都補足三位,不滿足的用0填充,這樣比較字典順序才是對的
* 怎麼補0呢?每一段的位數都不同,補0的個數也不一樣。
* 技巧:乾脆按照所需的最多的0的個數來補,每一段都補兩個0
* 有的地址段超出了三位,取每一段的最後三位
* 排序完後,有的地址前面多了0,去掉前面的0
*/
String ip_str="23.12.10.5 192.168.100.322 3.3.3.3 10.10.10.10 ";
ip_str=ip_str.replaceAll("(\\d+)", "00$1"); //每一段補兩個0
System.out.println(ip_str); //0023.0012.0010.005 00192.00168.00100.00322 003.003.003.003 0010.0010.0010.0010
ip_str=ip_str.replaceAll("0*(\\d{3})", "$1"); //取每一段的最後三位,
X* |
X,零次或多次 |
String[] ips=ip_str.split(" +");
Arrays.sort(ips);
for(String s:ips)
{
System.out.println(s.replaceAll("0*(\\d+)", "$1")); //去掉前面的0
}
}
privatestaticvoid test1()
{
/*
*案例一:我我....我..........我我...我我我....要要...要要...要要要.....學學..學學..學..學學學.學學學....學學學學軟..軟軟......件件件..件件件件件.件
*實現:我要學軟體
*
*思路:
*1.使用正則表示式
*2.先把所有的.去掉
*3.替換疊詞。
*/
String str="我我....我..........我我...我我我....要要...要要...要要要.....學學..學學..學..學學學.學學學....學學學學軟..軟軟......件件件..件件件件件.件";
String newStr=str.replaceAll("\\.+", "");
String str2=newStr.replaceAll("(.)\\1+", "$1");
System.out.println(str2);
}
}
importjava.io.BufferedReader;
importjava.io.File;
importjava.io.FileReader;
importjava.io.IOException;
importjava.io.InputStream;
import java.io.InputStreamReader;
importjava.net.URL;
importjava.net.URLConnection;
importjava.util.ArrayList;
importjava.util.List;
importjava.util.regex.Matcher;
importjava.util.regex.Pattern;
publicclass WebCrawlersDemo
{
publicstaticvoid main(String[] args) throws IOException
{
/*
* 網路爬蟲:其實就是一個應用程式,獲取網路中的指定資訊(符合指定規則的資訊)。
*
* 網路中的郵件地址。
*/
File file=new File("mail.txt");
String str="http://bbs.tianya.cn/post-enterprise-401802-1.shtml";
String regex="\\[email protected]\\w+(\\.\\w+)+";
//List<String> list=getMails(file,regex);
List<String> list=getMailByNet(str,regex);
for(String mail:list)
{
System.out.println(mail);
}
}
publicstatic List<String>getMailByNet(String str_url,String regex) throws IOException
{
//1.將str_url封裝成URL物件。
URL url=new URL(str_url);
List<String> list=new ArrayList<String>();
//2.開啟連線
URLConnection conn=url.openConnection();
//3,獲取讀取流
InputStream in=conn.getInputStream();
//封裝成BufferedReader物件
BufferedReader bufr=new BufferedReader(newInputStreamReader(in));
Pattern p= Pattern.compile(regex);
String line=null;
while((line=bufr.readLine())!=null)
{
//System.out.println(line);
Matcher m=p.matcher(line);
while(m.find())
list.add(m.group());
}
bufr.close();
returnlist;
}
privatestatic List<String> getMails(Filefile, String regex) throws IOException
{
//1.讀取檔案
List<String> list=new ArrayList<String>();
BufferedReader bufr=new BufferedReader(new FileReader(file));
Pattern p= Pattern.compile(regex);
String line=null;
while((line=bufr.readLine())!=null)
{
//System.out.println(line);
Matcher m=p.matcher(line);
while(m.find())
list.add(m.group());
}
bufr.close();
returnlist;
}
}