跟着老毕学Java之正则表达式

来源:互联网 发布:怎么看mac激活时间 编辑:程序博客网 时间:2024/06/05 10:46

------- android培训java培训、期待与您交流! ----------
————————————————————————————————————————————

正则表达式

正则表达式的特点

正则表达式:符合一定规则的表达式。

用途:用于专门操作字符串数据。

特点:用于一些特定的符号来表示一些代码操作,这样就简化了书写。学习正则表达式,就是学习这些符号。

好处:可以简化对字符串的复杂操作。

正则表达式的基本符号

 

            

字符类

[abc]

abc(简单类)

[^abc]

任何字符,除了abc(否定)

[a-zA-Z]

a zAZ,两头的字母包括在内(范围)

[a-d[m-p]]

a dmp[a-dm-p](并集)

[a-z&&[def]]

def(交集)

[a-z&&[^bc]]

a z,除了bc[ad-z](减去)

[a-z&&[^m-p]]

a z,而非mp[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]

Greedy 数量词

 

X?

X,一次或一次也没有

 

X*

X,零次或多次

 

X+

X,一次或多次

 

X{n}

X,恰好n

 

X{n,}

X,至少n

 

X{n,m}

X,至少n次,但是不超过m

 

     

边界匹配器

^

行的开头

$

行的结尾

\b

单词边界

\B

非单词边界

\A

输入的开头

\G

上一个匹配的结尾

\Z

输入的结尾,仅用于最后的结束符(如果有的话)

\z

输入的结尾

 

 

组和捕获

捕获组可以通过从左到右计算其开括号来编号。例如,在表达式((A)(B(C)))中,存在四个这样的组:

组1.((A)(B(C)))   组2.\A       组3.(B(C))       组4.(C)

组零始终代表整个表达式。

之所以这样命名捕获组是因为在匹配中,保存了与这些组匹配的输入序列的每个子序列。捕获的子序列稍后可以通过 Back引用在表达式中使用,也可以在匹配操作完成后从匹配器获取。

与组关联的捕获输入始终是与组最近匹配的子序列。如果由于量化的缘故再次计算了组,则在第二次计算失败时将保留其以前捕获的值(如果有的话)例如,将字符串"aba"与表达式(a(b)?)+相匹配,会将第二组设置为"b"。在每个匹配的开头,所有捕获的输入都会被丢弃。

(?)开头的组是纯的非捕获组,它不捕获文本,也不针对组合计进行计数。

使用注意事项:

1、 在切割中如果是使用“.”切割,正则表达式为”\\.”

2、 在替换中,如果正则表达式中的一部分代表的内容还想被使用,可以先把这部分用()括起来,然后用“$组序号”来代表要保留的内容。

 

 

正则表达式的功能

1.      用于匹配,String类的match(regex)方法。

2.      用于切割,String类的split(regetx)方法。

3.      用于替换,String类的replaceAllregex,repalcement)方法。

4.      用于复杂的获取,与PatternMatcher配合使用来获取。

匹配-切割-替换

class  RegexDemo{public static void main(String[] args) {//匹配示例//checkQQ();//checkTel();//切割示例//splitDemo("zhangsan.lisi.wangwu","\\.");//splitDemo("c:\\abc\\a.txt","\\\\");//splitDemo("erkktyqquio","");//按照叠词完成切割。为了让规则的结果被重用,可以将规则封装成一个组,用()完成,//组的出现都有编号,从1开始,想要使用自己有多大组可以通过 \n(n就是租的编号)的形式来获取。//替换示例String str="tel31321131ty13213211223gdfg13211321fsd";replaceAllDemo(str,"\\d{5,}","#");//将字符串中的数字替换成&。String str1 = "erkkkkadfassssweoiakjfiiiiaao";//将叠词提出成&。//replaceAllDemo(str1,"(.)\\1+","&");//将重叠的字符替换成单个字母。iiii>>i 用 $ 获取前一个正则表达式的组。replaceAllDemo(str1,"(.)\\1+","$1");}/*-----------------------------替换--------------------------------------*/public static void replaceAllDemo(String str,String reg,String newStr){System.out.println(str);str = str.replaceAll(reg,newStr);System.out.println(str);}/*-----------------------------切割--------------------------------------*/public static void splitDemo(String str,String reg){//String str ="zhangsan.lisi.wangwu";//str = "c:\\abc\\a.txt"//String reg =" +";//按照多个空格来进行切割(" {1.}")//String reg = "\\.";//"."是正则表达式符号,表示任意符号。\.表示正则表达式中的点//reg = ""String [] arr = str.split(reg);System.out.println(arr.length);for(String s:arr){System.out.println(s);}}/*------------------------------匹配--------------------------------------*//*需求:手机号段13***,15***,18****/public static void checkTel(){String tel ="1873190325";String teReg = "1[358]\\d{9}";boolean flag = tel.matches(teReg);System.out.println(flag);}/*需求一:对QQ号码进行校验,要求:5~15位,0不能开头,只能是数字。*///第一种方式:最简单,使用正则表达式。public static void checkQQ(){String qq = "12345618";String regex = "[1-9]\\d{4,14}";boolean flag = qq.matches(regex);System.out.println(flag);if(flag)System.out.println(qq+"........is ok");elseSystem.out.println(qq+"........不合法");}//第二种方式:利用非正则表达式来做。public static void checkQQ_1(){/*非正则方式二,使用了String类中中的方法,进行组合完成了需求,但是代码过于复杂。*/String qq = "122454551a";int len =qq.length();if(len>=5 && len <=15){//更简单的方式。try{long l = Long.parseLong(qq);System.out.println("qq:"+qq);}catch (NumberFormatException e){System.out.println("出现非法字符.....");}}else{System.out.println("长度错误");}/* 非正则方式一,最麻烦。if(!qq.startsWith("0")){char [] arr = qq.toCharArray();boolean flag = true;//定义标记for(int x = 0;x<arr.length;x++){if(!(arr[x]>='0' && arr[x]<='9')){flag = false;break;}}//根据标记值输出响应的提示信息if(flag){System.out.println("qq:"+qq);}else{System.out.println("出现非法字符");}}else{System.out.println("不可以0开头");}*/}}


 

获取

获取:将字符串中符合规则的子串取出。

操作步骤

1将正则表达式封装成对象。

2.让正则对象和要操作的字符串相关联。

3.关联后,获取正则匹配引擎。

4.通过引擎对符合规则的子串进行操作,比如取出。

示例代码

import java.util.regex.*;class RegexDemo2 {public static void main(String[] args) {getDemo();}//获取只有3个字符组成的单词。public static void getDemo(){String str = "ming tian jiu yao fang jia la ,da jia.";System.out.println(str);String reg = "\\b[a-z]{4}\\b";// \b表示单词边界。//1.将规则封装成对象。Pattern  p =Pattern.compile(reg);//2.让正则对象和要作用的字符串相关联。获取关联字符串的匹配器对象。Matcher m = p.matcher(str);//3.使用匹配引擎进行各种操作,如查找、匹配、获取等。/*System.out.println(m.matches());matches是匹配整个字符串。其实,String类中的mathes方法用的就是Pattern和Matches对象俩完成的。只不过被String的方法封装后,用起来较为简单,但是功能却单一。boolean b = m.find();//将规则作用到字符串上,并进行符合规则的子串查找。System.out.println(b);System.out.println(m.group());//用于获取匹配后的结果,使用前必须先进行匹配操作。*/System.out.println(m.matches());m.reset();//这句注释掉,while循环执行结果会少一个mingwhile(m.find())//判断符合规则的子串是否存在,它开始查找的结果是上次匹配后的指针位置{System.out.println(m.group());//取出这个符合规则的子串。System.out.println(m.start()+"...."+m.end());//m.gruop取出的子串在原字符串的开始和结束角标,注意角标包含头不包含尾。}/* *注意:同一个匹配器 ,每匹配一次,角标指针就向后移动一次,下次匹配的开始位置是上次匹配的结束位置。 *如果已经匹配过后,又要从新查找匹配,可以说使用匹配器的reset()方法,将指针归0。 */}}


 

如何判断选取那种功能

到底用四种功能中的哪一个呢?或者那几个呢?

1.如果只想知道该字符串是对是错,使用匹配。

2.想要将已有的字符串编程另一个字符串,使用替换。

3.想要按照指定的方式将字符串变成多个字符串,使用切割,获取规则以外的子串。

4.想要拿到符合需求的字符串子串,使用获取,符合规则的子串。

 

练习

去叠词、IP地址排序、邮件校验

import java.util.*;class RegexTest  {public static void main(String[] args) {//test_1();//ipSort();checkMail();}/*需求3:对邮件地址进行校验。这个必须掌握*/public  static void checkMail(){String mail ="asdfas12@sina.com.cn";//mail = "1@1.1";String reg = "[a-zA-Z0-9_]+@[a-zA-Z0-9]+(\\.[a-zA-Z]+){1,3}";//reg = "\\w+@\\w+(\\.\\w+)";//相对不太精确的匹配。//mail.indexOf("@")!=-1;这种方式不要用。System.out.println(mail.matches(reg));} /* 需求2: 将下边的ip地址段进行地址段顺序的排序。 192.168.1.15 23.48.56.109 10.73.91.18 254.253.252.1 1.23.25.26 思路: 还按照字符自然顺序,只要让它们每一段都是3位即可, 1.按照每一段需要的最多的0进行补齐,那么每一段就会至少保证有3位。 2.将每一段只保留三位,这样所有的ip地址都是每一段3位。 */ public static void ipSort() {String ip = "92.168.1.15 23.48.56.109 10.73.91.18 254.253.252.1 1.23.25.26";ip = ip.replaceAll("(\\d+)","00$1");System.out.println(ip);ip = ip.replaceAll("0+(\\d{3})","$1");String [] arr = ip.split(" +");//Arrays.sort(arr);//如果有重复的IP地址并要获取,那么必须用这个TreeSet<String> ts = new TreeSet<String>();for(String str:arr){//System.out.println(str);ts.add(str);}for(String s:ts){System.out.println(s.replaceAll("0+(\\d+)","$1"));}/*Iterator<String> it = ts.iterator();while(it.hasNext()){String str = it.next();str=str.replaceAll("0+(\\d+)","$1");System.out.println(str);}*/ }/* * 需求1:将下列字符串转成:我要学编程。 */public static void test_1(){String str = "我我.....我我我我我....我要...要要......要学.....学学学...编编编..编程.程.....程程程...程";System.out.println(str);/*将已有字符串变成另一个字符串,使用 替换功能。1.先将. 去掉。2.再将多个重复的内容变成单个内容。*/str = str.replaceAll("\\.","");str = str.replaceAll("(.)\\1+","$1");System.out.println(str);}}

 

网页爬虫

网络爬虫,是搜索引擎的的原理之一,它可以用来检索网络上的信息。

 

/*网页爬虫(蜘蛛)*/import java.io.*;import java.util.regex.*;import java.net.*;class  RegexTest2{public static void main(String[] args) throws IOException{getMails_2();}//需求2:从网页上获取邮件地址public static void getMails_2() throws IOException{//建立应用层用于连接的端点URLConnectionURL 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对象。String reg = "\\w+@\\w+(\\.\\w+)+";Pattern p = Pattern.compile(reg);while((line = bufIn.readLine())!=null){//获取与某一字符串的关联的正则表达式配适器。Matcher m = p.matcher(line);while(m.find()){System.out.println(m.group());}}}/*需求1:获取指定文档中的邮件地址。使用获取功能。Pattern Matcher*/public static void getMails() throws IOException{//http://localhost:8080/myweb/mail.htmlBufferedReader bufr = new BufferedReader(new FileReader("mail.txt"));String line = null;String reg = "\\w+@\\w+(\\.\\w+)+";Pattern p = Pattern.compile(reg);while((line = bufr.readLine())!=null){Matcher m = p.matcher(line);while(m.find()){System.out.println(m.group());}}}}


 

 


————————————————————————————————————————————

------- android培训java培训、期待与您交流! ----------