黑马程序员——Java之正则表达式

------------------- Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ---------------------

一、正则表达式


正则表达式是Java处理字符串、文本的重要工具。


Java对正则表达式的处理集中在以下两个两个类:

java.util.regex.Matcher   匹配类:用模式匹配一个字符串所表达的抽象结果。

java.util.regex.Pattern   模式类:用来表示一个编译过的正则表达式。

1、正则表达式特点

正则表达式是符合一定规则的表达式,

作用:用于专门操作数据。

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

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

弊端:符号定义越多,正则越长,阅读性越差。

具备的操作功能

2、正则中容易混淆的问题

(1)Java对反斜线处理的问题

在其他语言中,\\表示要插入一个字符\;

在Java语言中,\\表示要插入正则表达式的反斜线,并且后面的字符有特殊意义。

 

看API文档:

预定义字符类

. 任何字符(与行结束符可能匹配也可能不匹配)

\d 数字:[0-9]

\D 非数字: [^0-9]

\s 空白字符:[ \t\n\x0B\f\r]

\S 非空白字符:[^\s]

\w 单词字符:[a-zA-Z_0-9]

\W 非单词字符:[^\w]

 

但是看看上面程序,对比下不难看出:

\d在实际使用的时候就写成了 \\d;

在Java正则表达式中,如果要插入一个\字符,则需要在正则表达式中写成\\\\,原因是下面的APIDoc定义\\表示一个反斜线。

但是如果在正则表示式中表示回车换行等,则不需要多添加反斜线了。比如回车\r就写作\r.

(2)Matcher.find()

尝试查找与模式匹配的字符序列的下一个子序列。此方法从字符序列的开头开始,如果该方法的前一次调用成功了并且从那时开始匹配器没有被重置,则从以前匹配操作没有匹配的第一个字符开始,即如果前一次找到与模式匹配的子序列则这次从这个子序列后开始查找。

(3)Matcher.matchers()

判断整个字符序列与模式是否匹配。当连续用Matcher对象检查多个字符串时候,可以使用

Matcher.reset():重置匹配器,放弃其所有显式状态信息并将其添加位置设置为零。

或者Matcher.reset(CharSequenceinput)  重置此具有新输入序列的匹配器。

来重复使用匹配器。

 

(4)组的概念

这个概念很重要,组是用括号划分的正则表达式,可以通过编号来引用组。组号从0开始,有几对小括号就表示有几个组,并且组可以嵌套,组号为0的表示整个表达式,组号为1的表示第一个组,依此类推。

 

例如:A(B)C(D)E正则式中有三组,组0是ABCDE,组1是B,组2是D;

A((B)C)(D)E正则式中有四组:组0是ABCDE,组1是BC,组2是B;组3是C,组4是D。

int groupCount():返回匹配其模式中组的数目,不包括第0组。

String group():返回前一次匹配操作(如find())的第0组。

String group(int group):返回前一次匹配操作期间指定的组所匹配的子序列。如果该匹配成功,但指定组未能匹配字符序列的任何部分,则返回 null。

int start(int group):返回前一次匹配操作期间指定的组所匹配的子序列的初始索引。

int end(int group):返回前一次匹配操作期间指定的组所匹配的子序列的最后索引+1。

 

(5)匹配的范围的控制

 

start() 返回以前匹配的初始索引。

end() 返回最后匹配字符之后的偏移量。

 

public boolean lookingAt()尝试将从区域开头开始的输入序列与该模式匹配。

与 matches 方法类似,此方法始终从区域的开头开始;与之不同的是,它不需要匹配整个区域。

如果匹配成功,则可以通过 start、end 和 group 方法获取更多信息。

返回:

当且仅当输入序列的前缀匹配此匹配器的模式时才返回true。

 

(6)Pattern标记

 

Pattern类的静态方法

static Pattern compile(String regex, intflags)

         将给定的正则表达式编译到具有给定标志的模式中。

其中的flags参数就是Pattern标记,这个标记在某些时候非常重要。

 

3、字符串的替换


String.replace(char oldChar, char newChar)

返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 而生成的。

String.replace(CharSequence target,CharSequence replacement)

使用指定的字面值替换序列替换此字符串匹配字面值目标序列的每个子字符串。

String.replaceAll(String regex, Stringreplacement)

使用给定的 replacement 字符串替换此字符串匹配给定的正则表达式的每个子字符串。

String.replaceFirst(String regex, Stringreplacement)

使用给定的 replacement 字符串替换此字符串匹配给定的正则表达式的第一个子字符串。

 

StringBuffer.replace(int start, int end,String str)

使用给定 String 中的字符替换此序列的子字符串中的字符。

StringBuilder.replace(int, int, java.lang.String)

使用给定 String 中的字符替换此序列的子字符串中的字符。

 

Matcher.replaceAll(String replacement)

替换模式与给定替换字符串相匹配的输入序列的每个子序列。

Matcher.replaceFirst(String replacement)

替换模式与给定替换字符串匹配的输入序列的第一个子序列。

 

4、字符串的切分


 String[] split(String regex)

根据给定的正则表达式的匹配来拆分此字符串。

 String[]split(String regex, int limit)

根据匹配给定的正则表达式来拆分此字符串。

 

当然,还有一个StringTokenizer类,可以用来切分字符串,但是现在SUN已经不推荐使用了。

转变下思路,其实用正则表达式也可以达到将字符串切分为段的目的。

 

5、总结练习


总结:

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

2.如果要将已有的字符串变成另一个字符串,使用替换。

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

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

 

class Test9
{
       //(1)匹配
       //要求:5~15,0不能开头,只能是数字。
       publicstatic void regex(String qq){
              Stringregex="[1-9]\\d{4,14}";//第一个字符1~9范围因为手机号最前面不能出现0,第二个为-~9范围,第三个表示16,
              booleanb=qq.matches(regex);
              System.out.println(b);
       }
       //手机号:13xxx,15xxx,18xxx;
       publicstatic void replacePhone(String s){
              Stringregex="1[3,5,8][0-9]{9}";
              booleanb=s.matches(regex);
              System.out.println(b);
       }
       //邮箱:xx@xx.xx.xx将IP地址进行地址段顺序的排序。
       publicstatic void replaceMail(String mail){
              Stringregex="[a-zA-Z0-9]+@[a-zA-Z0-9]+(\\.[a-zA-Z]+)+";
              //简写:regex="\\w+@\\w+(\\.\\w+)+";
              booleanb=mail.matches(regex);
              System.out.println(b);
       }
       //(2)切割
       //可以按照叠词进行切割,为了可以让规则的结果可以被重用,可以将规则封装成一个组,用()完成。组的出现都有编号,从1开始,想要使用已有的组可以通过\n(n是组的编号)的形式来获取。
       publicstatic void splitDemo(String s){
              Stringregex="(.)\\1+";
              String[]str=s.split(regex);
              for(Stringss:str){
                     System.out.println(ss);
              }
       }
       //(3)替换
       //练习:将下列字符串转成:我要学编程;
       publicstatic void replaceAllDemo(String s){
              Stringregex="\\.+";
              Stringstr=s.replaceAll(regex,"");
              System.out.println(str);
              regex="(.)\\1+";
              str=str.replaceAll(regex,"$1");
              System.out.println(str);
       }
       publicstatic void replaceAllDemo1(String ip){
              Stringregex="(\\d+)";
              ip=ip.replaceAll(regex,"00$1");
              System.out.println(ip);
              regex="0*(\\d{3})";
              ip=ip.replaceAll(regex,"$1");
              System.out.println(ip);
              String[]arr=ip.split(" +");
              Arrays.sort(arr);
              for(intx=0;x<arr.length;x++){
                     System.out.println(arr[x]);
              }
       }
       //(4)获取
       publicstatic void toObtain(String s){
              Stringregex="\\b[a-z]{2}\\b";//将规则封装成正则对象。
              Patternp=Pattern.compile(regex);//将正则封装到模式中。
              Matcherm=p.matcher(s);//正则对象和要操作的字符串相关联,获取匹配器引擎对象matcher。
              //其实String中的matchers方法,用的就是pattern和matchers对象来完成的。只不过被String对象封装后,用起来较为简单,功能单一,如果复杂的就要使用matchers
              while(m.find()){//将规则匹配到字符串上。
                     Stringstr=m.group();//获取匹配到的子串
                     System.out.println(str+"----");
              }
       }
       //网络爬虫。获取互联网上的邮箱。
       publicstatic void webCrawler(){
              try{
              URLurl=newURL("http://blog.sina.com.cn/s/blog_515617e60101e151.html");//把url地址封装成URL对象。
              URLConnectionconn=url.openConnection();//获取远程对象的链接。
              BufferedReaderbr=new BufferedReader(new InputStreamReader(conn.getInputStream()));//远程对象链接获取到输入流,转换成字符流。
              BufferedWriter bw=new BufferedWriter(newFileWriter("E:\\IO\\邮件大全.txt"));
 
              Stringregex="\\w+@\\w+(\\.\\w+)+";//定义获取输入流中元素的规则。
              Patternp=Pattern.compile(regex);//规则封装成模式。
              Stringline=null;
              while((line=br.readLine())!=null){
                     Matcherm=p.matcher(line);//模式与读取到的字符关联起来。
                     while(m.find()){//查找字符匹配规则的字符。
                            Stringss=m.group();//获取匹配成功的数据。
                            bw.write(ss);
                            bw.newLine();
                            bw.flush();
                     }
              }
              br.close();
              bw.close();
              }
              catch(Exceptione){
                     thrownew RuntimeException("读取失败");
              }
       }
       publicstatic void main(String[] args){
              Stringqq="12522";
              regex(qq);
             
              Stringphone="15212345678";
              replacePhone(phone);
 
              Stringmail="liuxinglai@sain.com";
           replaceMail(mail);
             
              Stringsp="s....ds...s..dd..";
              splitDemo(sp);
             
              Strings="我...要要要......学学学..学学.编.编编编..编...程程程..程..程..";
              replaceAllDemo(s);
             
              Stringip="192.168.1.254   102.12.65.236   10.10.10.10  2.2.2.2 8.109.66.22";
           replaceAllDemo1(ip);
             
              Stringhq="da jia hao , cai shi zheng de hao";
              toObtain(hq);
 
              webCrawler();
       }
}


------------------- Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ---------------------
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值