教育行業(yè)A股IPO第一股(股票代碼 003032)

全國(guó)咨詢/投訴熱線:400-618-4000

Java培訓(xùn)之正則表達(dá)式

更新時(shí)間:2016年06月30日15時(shí)44分 來(lái)源:傳智播客Java培訓(xùn)學(xué)院 瀏覽次數(shù):

  1. 正則表達(dá)式概述:
首先是表達(dá)式,是一種正確的規(guī)則去進(jìn)行某一種是事物的操作,用于對(duì)字符串進(jìn)行操作的表達(dá)式,用于對(duì)字符串進(jìn)行的操作
好處:代碼更為簡(jiǎn)潔、提供了一些符號(hào)來(lái)表示一些規(guī)則,其實(shí)這個(gè)規(guī)則內(nèi)部還是有具體的代碼來(lái)完成對(duì)字符串操作。簡(jiǎn)單說(shuō):好像是將代碼進(jìn)行封裝、用符號(hào)進(jìn)行了替代。
弊端:正因?yàn)槭欠?hào)表示的,所以要記住很多符號(hào)的使用,而且符號(hào)多了閱讀性極差。
Eg:對(duì)QQ號(hào)碼進(jìn)行校驗(yàn)
要求:1、必須是5到15位。

  1. 必須是數(shù)字
  2. 0不可以開頭
String qq="234234234";
String regex="[1-9][0-9]{4,14}";這就是規(guī)則,作用在字符串上的規(guī)則。
Boolean b=qq.matches(regex);

  1. 正則表達(dá)式常見體現(xiàn):
其實(shí)就是一些常見符號(hào)的注解,必須要了解,學(xué)習(xí)正則,其實(shí)就是在學(xué)習(xí)這些符號(hào)的使用。
字符類:
[abc]:要是a或者b或者c
[^bac]:除了abc什么都行
[a-zA-Z]必須是字母
[a-b[m-p]]:a到b或者m到p
預(yù)定義字符:
.:任何字符,與行結(jié)束符可能匹配也可能不匹配
\d:數(shù)字[0-9]它是一個(gè)符號(hào),不要以為是兩個(gè)符號(hào),不是轉(zhuǎn)義。
\D:非數(shù)字[^0-9]
\s:空白字符
\S:非空白
\w:單詞字符,[a-zA-Z_0-9]字符數(shù)字下劃線
\W:非單詞
邊界匹配器:
\b:單詞邊界

數(shù)量詞
X?:一次或者一次也沒(méi)有
X*:沒(méi)有或有多次
X+:必有有一次或者多次
X{n}:恰好n次
X{n,}:至少n次
X{n,m}:n到m次之間

  1. 正則表達(dá)式常用的功能:(重點(diǎn))
  1. 匹配:
其實(shí)是用的就是String類中的matches方法,將正則作用到指定的字符串上判斷該字符串是否符合規(guī)則,返回真假。
Eg:手機(jī)校驗(yàn)號(hào)碼(面試題):
Public static void checkTel(){
String tel="13802920021";
Boolean b=tel.matches(regex);
String regex="1[358][0-9]{9}";
//String regex="1[358]\\d{9}";
}
注意:在字符串中單\代表的是轉(zhuǎn)義字符,所以為了保持原樣必須把它表示原樣性用\\來(lái)表示。
 

  1. 切割:
其實(shí)就是使用的是String類中的split方法,將字符串按照指定的規(guī)則,變成一個(gè)字符數(shù)組,凡是參數(shù)是regex都是正則。
Eg:切割字符串
Public static void splitString(){
String str="lisi.wangwu.zhaoliu";
String regex="\\.";
String[] arr=str.split(regex);
 
For(String s:arr){
Sop(s);
}
}
復(fù)雜切割:
Str="wwadhdhffffhehe";用疊詞來(lái)切割
String regex="(.)\\1+";
正則里面封轉(zhuǎn)是用()來(lái)進(jìn)行的,拿小括號(hào)一封裝會(huì)自動(dòng)分組,會(huì)有自動(dòng)的編號(hào),從1開始編號(hào),組:是正則中封裝的一種體現(xiàn),不寫封裝都不能寫編號(hào)。。
(.)(\\d)\\2:代表的是取第二組
Eg:((A)(B(C)))有幾組?
到底有幾組和每組有誰(shuí),只看左括號(hào)就行了
1:((A)(B(C)))
2:(A)
3:(B(C))
4:(C)

  1. 替換:
其實(shí)用的是String類中的replaceAll()方法
Eg:替換字符串:
Public static void replaceString(){
String str="abcuuufl";
Str=str.replaceAll("\\d{5,}","***");
 
Str="acdxxxxxxshdsYYYYsdahj";疊詞替換成一個(gè)字
Str=str.replaceAll("(.)\\1+","$1");
Sop(str);
}

  1. 獲?。?/span>
其實(shí)就是使用了正則表達(dá)式對(duì)象,java.util.Pattern.
  1. 先將正則表達(dá)式編譯成Pattern對(duì)象
  2. 將Pattern對(duì)象將和要匹配的字符串關(guān)聯(lián),獲取對(duì)應(yīng)的匹配器對(duì)象。
Matcher
  1. 通過(guò)匹配器對(duì)象Matcher對(duì)字符串進(jìn)行操作了。
Public static void getString(){
String str="da jia zhu yi le ,ming tian bu fang jia";
String regex="\\b[a-z]{3}\\b";\b:單詞邊界
Pattern p=Pattern,compile(regex);
P.mecther(str);
Matcher m=p.matcher(str);
While(m.find){
Sop(.m.group);//group方法可以返回查找到的子序列、
}
}

  1. 練習(xí):
1、我我..我我我...我要要...要要學(xué)...學(xué)學(xué)學(xué)...學(xué)編編....編編....程程...程.. .程
我要學(xué)編程
public static void test_1(){
String str="";
使用替換功能
1、先將點(diǎn)去掉。
st=str.replaceAll("\\.","");
2、將疊詞替換成一個(gè)
str=str.replaceAll("(.)\\1+","$1");
}
2、192.168.1.100 2.2.2.2 127.0.0.1 36.34.1.89
要求對(duì)這些ip地址進(jìn)行地址段的排序
思路:
1、按照字符串的順序比較,但是ip地址每一段位數(shù)不同。會(huì)出現(xiàn)錯(cuò)誤
所以將每一段都補(bǔ)成三位,就可以用字符串的字典順序比較了、
為了補(bǔ)位方便,按照最大的補(bǔ)位個(gè)數(shù)進(jìn)行補(bǔ)位。
String ip="192.168.1.100   2.2.2.2     127.0.0.1   36.34.1.89";
每一段都補(bǔ)兩個(gè)0,
ip=ip.replaceAll("(\\d)+","00$1");
獲取每一段的最后三位
ip=ip.replaceAll("0*(\\d{3})","$1");

String[] ips=ip.split("" +);
TreeSet<String> ts=new TreeSet<String>();
for(String s:ips){
ts.add(s);
}
for(String s:ts){
sop(s.replaceAll("0*"));
}

3、練習(xí)三:對(duì)email地址進(jìn)行校驗(yàn)
public static void test_3(){
String mail="abc12@sina.com";
String regex="\\w+@[a-zA-Z0-9]+(\\.[a-zA-Z]{2,3}){1,3}";
boolean b=mail.matches(regex);
sop(b);

}
4、網(wǎng)頁(yè)爬蟲<重點(diǎn)>參考:GetMainlsTest.java
其實(shí)就是一個(gè)小程序,不端的獲取網(wǎng)絡(luò)中符合規(guī)則的數(shù)據(jù)。
定義一個(gè)郵件爬蟲。
public static void getMails(){
File file=new File("");
BufferedReader bufr=new BufferedReader(
new FileReader(file));

String regex="\\w+@[a-zA-Z0-9]+(\\.[a-zA-Z]{2,3}){1,3}";
Pattern p=Pattern.compile(regex);
String line=null;
while((line=bufr.readLine())!=null){
Matcher m=p.matcher(line);
while(m.find()){
Sop(m.group());
}
sop(line);
}}
如果是網(wǎng)絡(luò)中:
String str_url="";
URL url=new URL(S);

  1. 反射技術(shù)(重要)
一個(gè)應(yīng)用可以加載后期出現(xiàn)的類,這種情況可以使用反射技術(shù)來(lái)完成。
首先告訴類名,直接尋找類名所對(duì)應(yīng)的class文件,并可以將其加載進(jìn)內(nèi)存,然后創(chuàng)建其對(duì)象,反射技術(shù)可以提高程序的擴(kuò)展性,連new對(duì)象都不用了,通過(guò)反射技術(shù)可以完成對(duì)指定名稱的類進(jìn)行對(duì)象的創(chuàng)建和內(nèi)容的調(diào)用,其實(shí)反射技術(shù)就是動(dòng)態(tài)獲取一個(gè)類,并獲取類中的所有內(nèi)容,簡(jiǎn)單說(shuō)反射就是對(duì)類的解剖。
獲取字節(jié)碼文件對(duì)象的三種方式:

  1. 通過(guò)Object中的getClass方法獲取。
Person p=new Person();
Class c1=p.getClass();
Person pp=new Person();
Class c2=pp.getClass();
Sop(c1==c2);true
因?yàn)閮?nèi)存只有一個(gè)通過(guò)字節(jié)碼文件創(chuàng)建的對(duì)象,雖然是創(chuàng)建了兩個(gè)對(duì)象,但是他們都是根據(jù)同一個(gè)字節(jié)碼創(chuàng)建的,描述等屬全部都一樣,所以創(chuàng)建的對(duì)象也是一樣的。
 

  1. 通過(guò)每一個(gè)具體數(shù)據(jù)類型具備的class靜態(tài)屬性就可以完成該類型的class對(duì)象的獲取,這種方式:必須要明確具體的類型,比如Person;
Class c=Person.class;
Class c1=int.class;

  1. 通過(guò)Class類中的方法,forName就可以完成Class對(duì)象的獲取,這種方式它的擴(kuò)展性最強(qiáng),不需要知道具體的類型、只要知道名字,就可以根絕名稱就可以去加載指定的類文件,不需要具備獲取class對(duì)象的類,前兩種方式必須知道class類,
Class clazz=Class.forName("cn.itcast.c.bean.Person");
為什么要加包名:因?yàn)榇颂幨亲址?,所以必須要寫全?br />  

  1. 獲取指定的字節(jié)碼文件中的屬性:字段:
Private static final String PERSON_STRING="cn.itcast.c.bean.person";
獲取指定名稱的字節(jié)碼文件對(duì)象
Class clazz=Class.forName(Person_String);
通過(guò)該字節(jié)碼文件對(duì)象的方法獲取字節(jié)碼文件中的字段:
Field[] fields=Clazz.getFields();//獲取所有的字段,只能拿到公共的屬性字段。
Fields=clazz.getDeclaredFields();//私有的東西都能拿到
For(Field field:fields){
Sop(field);
}

  1. 獲取指定名稱的字段:
Class clazz=Class.forName(person_string);
Field field=clazz.getField("name");
獲取字段,但是對(duì)于非靜態(tài)的字段,必須要有所屬的對(duì)象,既然需要該類的對(duì)象,就可以通過(guò)class類中的newInstance方法來(lái)完成,該類實(shí)例的創(chuàng)建。
Object obj=clazz.newInstance();本身就是在調(diào)用空參數(shù)列表構(gòu)造函數(shù)來(lái)完成的。
給指定字段賦值。
Field.set(obj,"lisi");
Object value=field.get(obj);
Sop(value);lisi

  1. 獲取私有字段:
Class clazz=Class.forName(person_string);
Field field=clazz.getDeclaredField("age");
field.setAccessible(true);取消對(duì)權(quán)限的檢查,暴力訪問(wèn),不建議使用
Field.set(obj,69);
Object value=field.get(obj);
Object obj=clazz.newInstance();
Sop(value);
 

  1. 如果沒(méi)有空參數(shù)構(gòu)造函數(shù)時(shí),要對(duì)其進(jìn)行初始化該怎么辦呢?
獲取類中的構(gòu)造函數(shù)來(lái)對(duì)指定類進(jìn)行對(duì)象的初始化。
Public static void getConsDemo(){
Class clazz=Class.forName(person_String);
Constructor cons=clazz.getConstructor(String.class);
Object obj=cons.newInstance("小強(qiáng)");
Field field=clazz.getField("name");
Object value=field.get(obj);
}
一般被反射的類都有一個(gè)空參數(shù)構(gòu)造函數(shù)

  1. 獲取指定類中的所有方法
Public static void getMethodsDemo(){
Class clazz=Class.forName(person_String);
Mthod[] methods=clazz.getMethods();
Methods=clazz.getDeclaredMethods();獲取私有的方法
For(Method method:methods){
Sop(method);
}
}
6、獲取指定方法
public static void getMethodDemo(){
Class clazz=Class.forName(person_string);
Method method=clazz.getMethod("show",null);
Object obj=clazz.newInstance();
method.invoke(obj,null);//調(diào)用invoke方法。要指定參數(shù)類型,但是這里是無(wú)參數(shù)的。
}
7、獲取一個(gè)帶參數(shù)的方法
public static void getparamMethodDemo(){
Class clazz=Class.forName(person_string);
Method method=clazz.getMethod("paramshow",String.class,int.class);

Object obj=clazz.newInstance();
method.invoke(obj,"小明",89);
}
8、獲取一個(gè)靜態(tài)方法
method.invoke(nul,null);不需要參數(shù),因?yàn)殪o態(tài)的都不需要對(duì)象
9、獲取一個(gè)私有方法。
Method method=clazz.getDeclaredMethod("privateShow",null);
Object pbj=clazz.newInstance();
method.setAccessible(true);
method.invoke(obj,null);

 
本文版權(quán)歸傳智播客Java培訓(xùn)學(xué)院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)注明作者出處。謝謝!
作者:傳智播客Java培訓(xùn)學(xué)院
首發(fā):http://m.8y3kgpwe.cn/javaee
0 分享到:
和我們?cè)诰€交談!