Java专题(四)之正则表达式详解

来源:互联网 发布:苹果如何用usb分享网络 编辑:程序博客网 时间:2024/05/16 12:51


什么是正则表达式:符合一定规则的表达式,它是专门操作字符串,它的好处在于可以简化对字符串的复杂操作。其实它是用一些特定的符号表示一些代码操作。所以在学习正则表达式,就是学习一些特殊符号的使用。但符号定义越多,正则越长,阅读性越差

 

常用的正则表达式符号:

a)     [ ]:用来确定括号中开始和结束的字符,例如[a-z],[1-9];

b)     [ ]:第二种意思是只能取包含里面的字符,如[358],[acghj];

c)     { }:用来表示前面子表达式的出现频率,比如[0-9]{4,14},说明0-9数字出现的次数要在414之间,即前面表达式长度是大于等于4且小于等于14。如果{3},表示出现的次数只能是三次

d)     \d:表示数字在0-9之间,在windows中要表示\\d,例如:[1-9]\\d

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

f)      \n:表示第几个字符,n代表的是取0-9之间任意的数字

g)     X+用来表示一个字符一次或多次出现,X代表的是任意字符。比如(空格)+a+

h)     X*表示一个字符零次或多次出现。,比如0*

i)       .:代表任意字符,如果想代表普通一个字符,就是\\.

j)       ():意思是的概念为了可以让规则的结果被重用,可以将规则封装成一个组,用()完成,组的出现都有编号,从1开始,想要使用已有的组可以通过\n的形式来获取,n就是组的编号,例如:(.)\\1:代表一个组,(.)代表任意字符,\\1代表的是拿第一个字符,即与(.)比较,如果相同就是叠词。

k)     $:代表的通常是取前面组的字符,和组一起用,也是从1开始,通过\n获取,它不是用在规则里面的,而是用在替换里取字符比较多。例如$1,就是取第一个元素

l)       \b:单词的边界,在window中要\\b

 

匹配

匹配:String matches方法,用规则匹配整个字符串,只要有一处不符合规则,就匹配结束,返回false

 

例如如下演示:

class RegexDemo

{

        publicstatic void main(String[] args)

        {

                  

                  //checkQQ_2();

                  check_3();

        }

        /*

        一个电话号码的数字,只能是131518开头,不能包含字母

        */

        publicstatic void check_3()

        {

                  Stringtel="13455698765";

                  Stringregix="[1][358]\\d{9}";//规则

                  System.out.println(tel.matches(regix));

        }

        /*

        QQ号,不能0开头,长度在55之间,不能包含字母

        */

        publicstatic void checkQQ_2()

        {

                  Stringqq="12a345";

                  Stringregix="[1-9][0-9]{4,14}";//规则

                  booleanflag=qq.matches(regix);

                  if(flag)

                           System.out.println("QQ:"+qq);

                  else

                           System.out.println("你输入的不合法");

        }

切割

切割:String split,根据给定正则表达式的匹配拆分此字符串。

 

代码演示下,切割在正则表达式的用法:

class RegexDemo

{

        publicstatic void main(String[] args)

        {

                  //checkQQ_2();

                  //check_3();

                  splitDemo("zhangsan lisi wangwu"," +");//按照多个空格切割

                  //按照点切割,由于点在正则表达式有特殊意思,所以加\\

                  splitDemo("zhangsan.lisi.wangwu","\\.");

                  splitDemo("c:\\abv\\1.txt","\\\\");//切割\\要加四个

                //按照叠词完成切割,+代表出现一次或多次

                  splitDemo("adaahgjbbbbkghiiilk","(.)\\1+");

        }

 

        publicstatic void splitDemo(String str,String regix)

        {

                  String[]name=str.split(regix);

                  System.out.println("------长度:"+name.length);

           for (String names:name)

           {

                           System.out.println(names);

           }

        }

 

 

替换

替换的方法:String replaceAll(String regex, Stringreplacement):使用给定的 replacement 替换此字符串所有匹配给定的正则表达式的子字符串。

 

代码演示:

class RegexDemo

{

        public static void main(String[] args)

        {

                  //将数字替换成*;

                  Stringstr="adas13456677ashggg3456";

                  replaceAllDemo(str,"\\d{5,}","*");

                  //将叠词替换成一个本身字符,$1代表的是取组的第一个字符。

                  Stringstr1="abcdfffjhkiiadkkads";

                  replaceAllDemo(str1,"(.)\\1+","$1");

        }

        public static voidreplaceAllDemo(String str,String regix,String newStr)

        {

                  System.out.println("---------分隔符-----------");

                  str=str.replaceAll(regix,newStr);

                  System.out.println(str);

        }

 

获取

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

 

操作步骤:

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

这个对象是在java.util.regex里的一个Pattern对象,

创建它的对象使用compile()方法。

Patternp=Pattern.compile(reg),reg代表传入的规则

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

Pattern的一个matcherString srt)方法,str代表的就是要作用的字符串

3.      关联后,获取正则匹配引擎(Matcher对象)

获取正则引擎就是Patternmatcher方法,返回的是Matcher对象

Matcherm=p.matcher(str);

4.      通过引擎对符合规则的子串进行操作。

Matcher有几种对子串的常用方法

a) booleanmatches():尝试将整个区域与模式匹配。其实String类中的matches方法,用的就是PatternMatcher对象来完成的,只不过被String的方法封装后,用起来较为简单,但功能却单一

b) StringreplaceAll(String replacement):替换模式与给定替换字符串相匹配的输入序列的每个子序列。

c) booleanfind():将规则作用到字符串上,并进行符合规则的子串查找。

d) Stringgroup():返回由以前匹配操作所匹配的输入子序列。即获取匹配后结果

e) intstart():返回以前匹配的初始索引

f)  intend():返回最后匹配字符之后的偏移量。即最后字符的索引

 

代码演示如下:

importjava.util.regex.*;

class RegixDemo2

{

        public static void main(String[] args)

        {

                  getDemo();

        }

        public static void getDemo()

        {

                  String str="ming tianjiu yao fang jia la ,da jia. ";

                  Stringregix="[a-z]{4}";//定义一个规则,用来取是四个字母组成单词

                  //将规则封装成对象

                  Patternp=Pattern.compile(regix);

                  //让正则对象和要作用的字符串相关联,获取匹配器对象

                  Matcher m=p.matcher(str);

                  //对字符串进行操作

                  while (m.find())

                  {

                           System.out.println(m.group());

                           System.out.println(m.start()+"......"+m.end());

                  }

 

        }

}

猜想:java jdk7是不是有自动取消单词边界的功能,当然可以加上\d的边界符号。

 

正则表达式应用

我们在对字符串进行正则表达式处理时,到底用四种功能中的哪一个呢?或者哪几个呢?

思路方式:

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

2.      想要将已有的字符串变成另一个字符串,替换。

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

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

 

应用一:将代码中一段重复的字符串转成,我要学编程

 

classTest

{

        public static void main(String[] args)

        {

                  test();

        }

        public static void test()

        {

                  /*

                  将已有的字符串变成另一个字符串,使用替换功能

                  */

                  String str="我我...我我...我要..学学..编编...";

                  //第一步:可以先将.去掉

                  str=str.replaceAll("\\.+","");

                  System.out.println("firstreplace"+str);

                  System.out.println("---------------------");

                  //第二步:再将重复的内容变成单个内容

                  str=str.replaceAll("(.)\\1+","$1");

                  System.out.println("endreplace"+str);

        }

}

 

应用二:192.168.254 102.49.23.01310.10.10.10 2.2.2.2 8.109.90.30这些ip地址进行地址段顺序的排序

思路:按照字符串自然排序,只要让它们每一段都是三位即可

1.      按照每一段需要的最多的0进行补齐,那么每一段就会至少保证三位

2.      将每一段只保留3位,这样,所有的ip地址都是每一段3

importjava.util.*;

classTest

{

        public static void main(String[] args)

        {

                  sortip();

        }

        public static void sortip()

        {

                  String str="192.168.254102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.30";

                  //第一步:将每个段都加上两个零

                  str=str.replaceAll("(\\d+)","00$1");

                  System.out.println(str);

                  //第二步:将多余的0去掉,每个段都要保留3

                  str=str.replaceAll("0*(\\d{3})","$1");

                  System.out.println(str);

                  //第三步:将空格切割掉每一个元素,放到数组里面

                  String[] s=str.split("");

                  //第四步:进行排序

                  TreeSet<String> set=newTreeSet<String>();

                  System.out.println("-----------最后结果--------");

                  for (String ss:s)

                  {

                           set.add(ss);

                  }

                  //第五步:打印排序后的ip,并将多余的去掉

                  for (String end:set)

                  {

                           System.out.println(end.replaceAll("0*(\\d+)","$1"));

                  }

        }

 

应用三:对邮件地址进行校验。

importjava.util.*;

classTest

{

        public static void main(String[] args)

        {

                  checkMail();

        }

        public static void checkMail()

        {

                  Stringstr="abc123@sina.com.cn";

                  //较为精确的匹配

                  Stringregix="[a-zA-Z0-9_]+@[a-zA-Z0-9]+(\\.[a-zA-Z]+){1,3}";

                  //较为不太精确的匹配

                  regix="\\w+@\\w+(\\.\\w+)+";

                  System.out.println(str.matches(regix));

        }

}

 

应用四:网页爬虫(蜘蛛)

既是将文档中的一段字符串获取指定的邮件地址,使用获取的功能的话,我们就用到了PatternMatcher对象

importjava.io.*;

importjava.util.regex.*;

importjava.net.*;

classRegexTest

{

        public static void main(String[] args)throws Exception

        {

                  getMails_1();

        }

        /*

        获取网页上的邮箱地址

        */

        public static void getMails_1()throwsException

        {

                  URL u=newURL("http://tieba.baidu.com/p/739117163");

                  URLConnectionconn=u.openConnection();

                  BufferedReader br=newBufferedReader(new InputStreamReader(conn.getInputStream()));

                  Stringreg="\\w+@\\w+(\\.\\w+)+";

                  Patternp=Pattern.compile(reg);

                  String line=null;

                  while((line=br.readLine())!=null)

                  {

                           Matcherm=p.matcher(line);

                           while (m.find())

                           {

                                    System.out.println(m.group());

                           }

                  }

        }

        /*

        获取本地上的邮箱地址

        */

        public static void getMails()throwsException

        {

                  BufferedReader br=newBufferedReader(new FileReader("mail.txt"));

                  Stringmailreg="\\w+@\\w+(\\.\\w+)+";

                  Patternp=Pattern.compile(mailreg);

                  String line=null;

                  while((line=br.readLine())!=null)

                  {

                           Matcherm=p.matcher(line);

                           while (m.find())

                           {

                                    System.out.println(m.group());

                           }

                  }

        }

}



原创粉丝点击