Java基础——正则表达式


 

1.   正则表达式

概念特点

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

    作用:用于专门操作字符串。

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

    所以学习正则表达式,就是在学习一些特殊符号的使用。

 

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

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

表达式--正则表达式的编译表示形式。

1)  字符

 

x

字符 x

\\

反斜线字符

\0n

带有八进制值 0 的字符 n (0 <= n <= 7)

\0nn

带有八进制值 0 的字符 nn (0 <= n <= 7)

\0mnn

带有八进制值 0 的字符 mnn(0 <= m <= 3、0 <= n <= 7)

\xhh

带有十六进制值 0x 的字符 hh

\uhhhh

带有十六进制值 0x 的字符 hhhh

\t

制表符 ('\u0009')

\n

新行(换行)符 ('\u000A')

\r

回车符 ('\u000D')

\f

换页符 ('\u000C')

\a

报警 (bell) 符 ('\u0007')

\e

转义符 ('\u001B')

\cx

对应于 x 的控制符

 

2)  字符类

[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](减去)

3)  预定义字符类

.

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

\d

数字:[0-9]

\D

非数字: [^0-9]

\s

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

\S

非空白字符:[^\s]

\w

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

\W

非单词字符:[^\w]

 

 

4)  边界匹配器

^

行的开头

$

行的结尾

\b

单词边界

\B

非单词边界

\A

输入的开头

\G

上一个匹配的结尾

\Z

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

\z

输入的结尾

 

5)  Greedy 数量词

X?

X,一次或一次也没有

X*

X,零次或多次

X+

X,一次或多次

X{n}

X,恰好 n 次

X{n,}

X,至少 n 次

X{n,m}

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

 

 

功能-匹配,切割,替换

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

   

2,切割:String split();

 

3,替换:String replaceAll(regex,str);如果regex中有定义组,可以在第二参数中通过$符号获取正则表达式中的已有的组。

 

请看如下示例:

 

class  RegexDemo

{

    publicstaticvoid main(String[] args) 

    {

       //demo();

       //System.out.println((char)11);

       //checkTel();

 

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

       //splitDemo("c:\\abc\\a.txt","\\\\");

       //splitDemo("erkktyqqquizzzzzo","(.)\\1+");

                  //按照叠词完成切割。为了可以让规则的结果被重用

                  //可以将规则封装成一个组。用()完成。组的出现都有编号。

                  //从1开始。想要使用已有的组可以通过  \n(n就是组的编号)的形式来获取。

                  //((())()):总共有4组,从左边起按"("算组的序号

 

       String str = "wer1389980000ty1234564uiod234345675f";//将字符串中的数字替换成#。

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

 

       String str1 = "erkktyqqquizzzzzo";//将叠词替换成$.  //将重叠的字符替换成单个字母。zzzz->z

       replaceAllDemo(str1,"(.)\\1+","$1");//“$1”获取前面规则中的第一个组的值

    

    }

 

    publicstaticvoid replaceAllDemo(String str,String reg,String newStr)

    {

       str = str.replaceAll(reg,newStr);

 

       System.out.println(str);

    }

 

    publicstaticvoid splitDemo(String str,String reg)

    {

       

       //String reg = " +";//按照多个空格来进行切割

       String[] arr = str.split(reg);  

       System.out.println(arr.length);

       for(String s : arr)

       {

           System.out.println(s);

       }

    }

 

    /*

    匹配

    手机号段只有 13xxx 15xxx 18xxxx

 

    */

    publicstaticvoid checkTel()

    {

       String tel = "16900001111";

       String telReg = "1[358]\\d{9}";

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

    }

 

    publicstaticvoid demo()

    {

       String str = "b23a23456789";

 

       String reg = "[a-zA-Z]\\d*";

       //String reg = "[bcd];//只能有一个字符,而且只能为bcd;

 

       boolean b= str.matches(reg);

       System.out.println(b);

    }

    publicstaticvoid checkQQ()

    {

       String qq = "123a454";

 

       String regex = "[1-9]\\d{4,14}";//“\\”表示"\"

 

       //String regex = "[1-9][0-9]{4,14}";//第一个字符是1-9。第二个字符是0-9,从第二个字符起,范围为4<X<=14个

 

       boolean flag = qq.matches(regex);

       if(flag)

           System.out.println(qq+"...is ok");

       else

           System.out.println(qq+"... 不合法");

    }

 

    /*

    对QQ号码进行校验

    要求:5~15  0不能开头,只能是数字

    

    这种方式,使用了String类中的方法,进行组合完成了需求。但是代码过于复杂。

    */

 

    publicstaticvoid checkQQ_1()

    {

       String qq = "1882345a0";

 

       int len = qq.length();

 

       if(len>=5 && len<=15)

       {   

           //通过基本数据类型对象包装类来判断非法字符

           if(!qq.startsWith("0"))//Integer.parseInt("12a");NumberFormatException

           {

              try

              {

                  long l = Long.parseLong(qq);//转换的时候回发生异常

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

              }

              catch (NumberFormatException e)

              {

                  System.out.println("出现非法字符.......");

              }

              

              /*普通方法检验非法字符

 

              char[] arr = qq.toCharArray();//123a4

              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开头");

 

           }

       }

       else

       {

           System.out.println("长度错误");

       }

    }

}
<span style="font-family:Calibri;font-size:14px;"> </span>

功能-获取

1)  概述

正则表达式的第四个功能。

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

 

2)  操作步骤:

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

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

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

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

 

示例如下:

import java.util.regex.*;

 

class MyIEByGUI//RegexDemo2 

{

    publicstaticvoid main(String[] args) 

    {

       getDemo();

    }

    publicstaticvoid getDemo()

    {

       String str = "ming tian jiu yao fang jia le ,da jia。";

       System.out.println(str);

       String reg = "\\b[a-z]{4}\\b";//第一个和第四个字符为边界

 

       //将规则封装成对象。

       Pattern p = Pattern.compile(reg);

 

       //让正则对象和要作用的字符串相关联。获取匹配器(引擎)对象。

       Matcher m  = p.matcher(str);

 

       //System.out.println(m.matches());//其实String类中的matches方法。用的就是Pattern和Matcher对象来完成的。

                                     //只不过被String的方法封装后,用起来较为简单。但是功能却单一。Match()尝试将整个区域与模式匹配,返回boolean。

       

       //将规则作用到字符串上,并进行符合规则的子串查找。查到即结束

       //boolean b = m.find();

       //System.out.println(b);

       //System.out.println(m.group());//用于获取匹配后结果。

       

       

       //System.out.println("matches:"+m.matches());//str不止4个字符,返回false,匹配器的索引位置已经到了第五个字符

       

       while(m.find())

       {

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

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

       }

    }

}
 

练习(邮箱校验-IP地址段排序-指定格式的字符串)

class RegexTest 

{

    publicstaticvoid main(String[] args) 

    {

       //test_1();

       //ipSort();

 

       checkMail();

    }

 

    /*

    需求:对邮件地址进行校验。(常见功能)

 

    */

    publicstaticvoid checkMail()

    {

       String mail = "abc12@sina.com.cn.cn";

 

       mail = "1@1.1";

 

       String reg = "[a-zA-Z0-9_]+@[a-zA-Z0-9]+(\\.[a-zA-Z]+)+";//较为精确的匹配。

       reg = "\\w+@\\w+(\\.\\w+)+";//相对不太精确的匹配。有些网站这样做,考虑到大家都知道邮箱格式

 

       //mail.indexOf("@")!=-1//很粗略

 

       System.out.println(mail.matches(reg));

    }

 

    /*

    需求:

    将下列字符串转成:我要学编程.

    

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

    思路方式:

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

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

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

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

    */

    publicstaticvoid test_1()

    {

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

       /*

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

       1,可以先将 . 去掉。

       2,在将多个重复的内容变成单个内容。

       */

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

       System.out.println(str);

 

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

       

       System.out.println(str);

 

    }

    /*

    192.68.1.254 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.30

    将ip地址进行地址段顺序的排序。

 

 

    还按照字符串自然顺序,只要让它们每一段都是3位即可。

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

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

 

    */

    publicstaticvoid ipSort()

    {

       String ip = "192.68.1.254 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.30";

 

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

       System.out.println(ip);

 

       ip = ip.replaceAll("0*(\\d{3})","$1");//组里面的优先返回给$1;00192,前面两个0,返回192,002前面零个0,返回002

       System.out.println(ip);

 

       String[] arr = ip.split(" ");

 

       /*排序方法1

       Arrays.sort(arr);

       

       for(String s : arr)

       {

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

       }*/

 

       //排序方法2

       TreeSet<String> ts = new TreeSet<String>();

 

       for(String s : arr)

       {

           ts.add(s);

       }

 

       for(String s : ts)

       {

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

       }

    }

}
 

网页爬虫(蜘蛛)

  

class RegexTest 

{

    publicstaticvoid main(String[] args) throws Exception

    {

       getMails_1();

    }

 

    publicstaticvoid getMails_1()throws Exception

    {

       URL url = new URL("http://127.0.0.1:8080/myweb/mymail.html");

 

       URLConnection conn = url.openConnection();

 

       BufferedReader bufIn = new BufferedReader(new InputStreamReader(conn.getInputStream()));

       

       String line = null;

 

       String mailreg = "\\w+@[a-zA-Z0-9]+(\\.[a-zA-Z]+)+";

       Pattern p = Pattern.compile(mailreg);

 

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

       {

           Matcher m = p.matcher(line);

           while(m.find())

           {

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

           }

       }

    }

 

    /*

    获取指定文档中的邮件地址。

    使用获取功能。Pattern  Matcher

    */

    publicstaticvoid getMails()throws Exception

    {

       BufferedReader bufr = 

           new BufferedReader(new FileReader("mail.txt"));

 

       String line = null;

 

       String mailreg = "\\w+@\\w+(\\.\\w+)+";

       Pattern p = Pattern.compile(mailreg);

 

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

       {

           Matcher m = p.matcher(line);

           while(m.find())

           {

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

           }

       }

    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值