Java SE 13_Regular Expression

来源:互联网 发布:建立寝室学生信息表sql 编辑:程序博客网 时间:2024/06/05 19:14

Java SE 13th day:正则表达式

1、本次课程知识点

 

1、正则表达式的作用

2、Pattern和Macher类

3、String对正则的支持

2、具体内容

正则表达式最早是在Linux下发展起来的,而在JDK1.4之后加入到Java的开发环境之中,在JDK 1.4之前如果要想使用正则表达式进行开发,则必须从网上单独下载Apache的一个正则的表达式的开发包,正则最早是从PHP中兴起的,主要的作用可以非常方便完成一些复杂的严整功能等基本实现。

2.1 认识正则(理解)

下面通过一个程序简单了解以下正则有哪些用处。

例如:现在有如下的一个要求:判断一个字符串是否由数字组成。

实现一:不使用正则

● 将字符串变为字符数组,之后将数组中的每个内容取出进行验证。

package org.lxh.regextdemo;

 

public class RegexDemo01 {

 

    public static void main(String[] args) {

       String str = "121s34123414123";

       char c[] = str.toCharArray();// 将字符串变为字符数组

       boolean flag = true;

       for (int i = 0; i < c.length; i++) {

           if (!(c[i] >= '0' && c[i] <= '9')) {//不是数字

              flag = false;

              break ;

           }

       }

       if(flag){

           System.out.println("字符串是由数字组成!");

       }else{

           System.out.println("字符串不是由数字组成!") ;

       }

    }

}

字符串不是由数字组成!

以上是实现了基本的操作,但是现在只是一个小小的验证,已经编写了很多的行,如果更加复杂的严整呢?

实现二:使用正则实现

package org.lxh.regextdemo;

 

public class RegexDemo02 {

 

    public static void main(String[] args) {

       String str = "121s34123414123";

       if (str.matches("\\d+")) {//使用正则

           System.out.println("字符串是由数字组成!");

       } else {

           System.out.println("字符串不是由数字组成!");

       }

    }

}

字符串不是由数字组成!

以上的操作明显比第一种实现更加容易,而且代码较少,那么在操作中使用的“\\d+”实际上就属于正则表达式。

2.2 正则表达式(核心,背

如果要想知道有多少种正则表达式,则观察java.util.regex包中的Pattern类,里面列出全部的正则表达式内容。

1、 表示单个字符:

1)  如果现在只是出现一个字母A或B,则意味着只能有这个字母所组成;

2)  \\:表示一个“\”,与char中的转义字符相同;

3)  \n:匹配换行的,与char中的转义字符相同;

字符匹配(Character classes)

No

表达式

描述

1

[abc]

表示取值可能是a,可能是b,可能是c

2

[^abc]

表示取值不是a、b、c的任意一个内容

3

[a-zA-Z]

表示全部的字母,大写和小写。[a-z]表示小写字母,[A-Z]表示大写字母

4

[0-9]

表示由数字组成

5

[^0-9]

表示由非数字组成

简短表达式(Predefined character classes)

No

表达式

描述

1

\d

表示由数字组成:[0-9]

2

\D

表示由数字组成:[^0-9]

3

\s

表示由空格组成,空格包含了“\n”、“\t”之类的:[ \t\n\x0B\f\r]

4

\S

表示由空格组成:[^\s]

5

\w

表示由字母、数字、下划线组成:[a-zA-Z_0-9]

6

\W

表示由字母、数字、下划线组成:[^\w]

7

.

表示任意字符

列出出现的次数(Greedy quantifiers、以X表示一个完整的正则)

No

表达式

描述

1

X?

表示正则表达式出现0次或1次

2

X*

表示正则表达式出现0次或1次或多次

3

X+

表示正则表达式出现1次或多次

4

X{n}

表示出现的长度正好是n次

5

X{n,}

表示出现的长度大于n次

6

X{n, m}

表示出现的长度正好是n到m次

关系运算(Logical operators)

No

表达式

描述

1

XY

X组正则之后紧跟着Y组正则

2

X|Y

要么是X的正则,要么是Y的正则

3

(X)

表示一组规范

界限表示(Boundarymatchers)

No

表达式

描述

1

^

表示正则的开始;

2

$

表示正则的结束

       在Java之中,所有的正则表达式不用编写开始和结束标记,但是在其他语言之中,就有可能需要,例如:JavaScript。

但是,如果要想使用以上的正则表达式,则需要Pattern类和Matcher类的支持。

在Pattern类中需要指定要操作的正则表达式规范,而在Matcher类进行验证。

2.3 正则编译(/匹配)类:Pattern(理解)

java.util.regex.Pattern类是正则操作的最重要的一个类,所有的正则规范需要在Pattern类中进行指定,此类的操作方法如下:

No

方法名称

类型

描述

1

public static Pattern compile(String regex)

普通

通过此方法取得Pattern实例,并设置正则

2

public Matcher matcher(CharSequence input)

普通

为Matcher类实例化

3

public String[] split(CharSequence input)

普通

字符串拆分

4

public String[] split(CharSequence input, int limit)

普通

按字符串拆分,并且指定拆分个数

5

public String pattern()

普通

返回使用的正则表达式

我们知道CharSequence是一个接口,类库中实现该接口的类有:CharBuffer, Segment, String,StringBuffer, StringBuilder。

在此类中构造方法被隐藏起来,所以需要通过compile进行对象的实例化操作,下面通过Pattern类完成一个拆分操作。例如:现在有如下的字符串“a1n123adfhu93534bfrgj”,要求按照数字拆分。

那么这种时候使用正则拆分是最方便的,因为如果按照之前的方法拆分,太麻烦了。

此时应该使用“\d”进行数字的匹配,但是每一个“\d”只能表示一个数字,在此情况下需要表示多次,所以要使用“\d+”,表示数字可能出现1次或多次。

范例:完成数字的拆分。

package org.lxh.regextdemo;

import java.util.regex.Pattern;

 

public class PatternDemo01 {

    public static void main(String[] args) {

       Pattern pat = Pattern.compile("\\d+");//实例化Pattern类对象

       String str = "a1n123adfhu93534bfrgj";

       String s[] = pat.split(str);// 进行字符串的拆分

       for (int i = 0; i < s.length; i++) {

           System.out.print(s[i] +"、");//输出

       }

    }

}

a、n、adfhu、bfrgj、

       此时应该可以发现,通过这种模式进行的字符串拆分,功能更强大。

范例:保留字母,拆分其他

package firstCourse;

import java.util.regex.Pattern;

 

public class APIDemo {

    public static void main(String[] args) {

        Pattern pat = Pattern.compile("[^a-zA-Z]+");//实例化Pattern类对象

        String str = "*&J@UH712h——+{iuz45a2mn";

        String s[] = pat.split(str);//进行字符串的拆分

        for (int i = 0; i < s.length; i++) {

            System.out.print(s[i] +"");//输出

        }

    }

}

       以上只是验证了两个正则,实际上根据业务的要求,可以随意的组合。

2.4正则操作类:Matcher类(理解)

Matcher类的主要功能是用于进行正则的匹配,通过Pattern类中定义的正则,再使用Mather类进行验证或者替换。

No

方法名称

类型

描述

1

public boolean matches()

普通

进行正则的匹配

2

public String replaceAll(String replacement)

普通

替换全部

3

public String replaceFirst(String replacement)

普通

替换第一个

下面使用操作验证以上的方法。

范例:进行字符串的验证

如果要进行字符串的验证操作,则需要Pattern类指定严整的正则,最终使用Matcher类进行匹配,例如,现在有如下的车牌号码的规定:“XXX-XX-XXX”,其中“X”表示一个个数字,现在给出一个车牌号码,验证此号码是否正确。

此时的正则表达式:“\\d{3}-\\d{2}-\\d{3}”。

之后使用Pattern类中的matcher()方法,设置要验证的字符串进行最终的验证。

package org.lxh.regexdemo;

 

import java.util.regex.Matcher;

import java.util.regex.Pattern;

 

public class MatcherDemo01 {

 

    public static void main(String[] args) {

       String str = "111-22-333";//定义字符串

       String pat = "\\d{3}-\\d{2}-\\d{3}";//定义正则

       Pattern p = Pattern.compile(pat);

       Matcher m = p.matcher(str);

       if (m.matches()) {// 执行验证

           System.out.println("验证成功!");

       } else {

           System.out.println("验证失败!");

       }

    }

}

验证成功!

范例:完成替换功能的实现

package org.lxh.regexdemo;

import java.util.regex.Matcher;

import java.util.regex.Pattern;

 

public class MatcherDemo02 {

 

    public static void main(String[] args) {

       String str = "1ss34fsdafsd567fsdafsd";//字符串由数字组成

       String regex = "\\d+";

       Matcher mat = Pattern.compile(regex).matcher(str);

       System.out.println(mat.replaceAll("*"));//替换

    }

}

*ss*fsdafsd*fsdafsd

以上的这些操作好像在String中都存在。实际上在JDK1.4之后String类就被修改了。

2.5 String类对正则的支持(重点

2.5.1、基本方法

在JDK 1.4之后加入了正则,随后又更新了String的操作类,因为在使用正则中,所有的内容通过字符串表示的比较多,在String类中有以下的方法可以完成对正则的支持:

No

方法名称

类型

描述

1

public boolean matches(String regex)

普通

指定正则规则,并进行验证

2

public String replaceAll(String regex,String replacement)

普通

字符串替换,支持正则

3

public String replaceFirst(String regex,String replacement)

普通

替换第一个,支持正则

4

public String[] split(String regex)

普通

字符串拆分,支持正则

在开发之中如果要想使用正则,基本上都直接使用String类,很少去直接使用Pattern类或Matcher类,因为       String的功能已经足够强大了。

范例:使用split完成拆分操作

● 给定一个IP地址,要求“.”拆分

package org.lxh.regexdemo;

 

public class StringSplit {

    public static void main(String[] args) {

       String ip = "192.168.0.1";

       String str[] = ip.split("\\.");//只要拆不开,就使用转义

       for (int x = 0; x < str.length; x++) {

           System.out.print(str[x] +"、");

       }

    }

}

192、168、0、1、

但是此时,又出现了一个问题,如果在ip地址前后都添加“.”呢?结果如下:

……

String ip = "...192.168.0.1...";

……

、、、192、168、0、1、

可以发现,在后面添加的“.”没有问题,但是前面的“.”经过拆分后会以“”””的形式存放于数组str[]中。

范例:解决以上问题。

public class Te {

    public static void main(String[] args) {

       String ip = "...192.168.0.1...";

       while (ip.startsWith(".")) {

           ip = ip.replaceFirst("\\.", "");

       }

       String str[] = ip.split("\\.");//只要拆不开,就使用转义

       for (int x = 0; x < str.length; x++) {

           System.out.print(str[x] +"、");

       }

    }

}

192、168、0、1、

范例:验证操作

● 验证一个email地址是否合法

● 正则:“\\w+@\\w+.\\w+”

package org.lxh.regexdemo;

 

public class StringMatches {

    public static void main(String args[]) {

       String ip = "aa@aa.com.cn"; // 定义email地址

       System.out.println(ip.matches("\\w+@\\w+\\.\\w+"));

    }

}

false

以上的验证非常方便的完成了,但是这样的正则存在问题!

对于email验证来说,域名的后缀只有有限的几个,所以,此时以上的验证并不符合真实的要求。

取值范围“com、com.cn、net、cn、org、edu、gov”。

package org.lxh.regexdemo;

 

public class StringMatches {

    public static void main(String args[]) {

       String ip = "aa@aa.net"; // 定义email地址

       System.out.println(ip

               .matches("\\w+@\\w+\\.(com|com.cn|net|cn|org|edu|gov)"));

    }

}

true

范例:验证字符串数据是否为日期格式,如果是则转换为Date型输出

import java.util.Date;

import java.text.ParseException;

import java.text.SimpleDateFormat;

 

public class Te {

    public static void main(String[] args) {

       String str = "2012-10-25";

       if (str.matches("\\d{4}-\\d{2}-\\d{2}")) {

           try {

              Date date = new SimpleDateFormat("yyyy-MM-dd").parse(str);

              System.out.println(date);

           } catch (ParseException e) {

              e.printStackTrace();

           }

       }

    }

}

Thu Oct 25 00:00:00 CST 2012

范例:给定一个字符串,判定其是否为小数,如果是则转换为double型

public class Te {

    public static void main(String[] args) {

        String data[] = { "182", "182.", "182.452", "12.3.4", ".4", ".4.12" };

        for (int x = 0; x < data.length; x++) {

            System.out.print(data[x] +"\t是否为小数:");

            if (data[x].matches("(\\.\\d+)|\\d+(\\.\\d+)")) {

                double d = Double.parseDouble(data[x]);//要熟记此方法

                System.out.println("是,→double型:" + d);

            } else {

                System.out.println("否!");

            }

        }

    }

}

182     是否为小数:否!

182.    是否为小数:否!

182.452 是否为小数:是,→double型:182.452

12.3.4  是否为小数:否!

.4      是否为小数:是,→double型:0.4

.4.12   是否为小数:否!

       要清楚parseDouble(str)和doubleValue()的区别和用法:Double.parseDouble(Stringstr)是static方法,用于把String类转换为double数据类型;而Double包装类中doubleValue()不是static方法,需要由实例化对象去调用,此方法用户取得Double包装类的对象返回double数据类型。

2.5.2、正则对中文的支持

在正则中,中文u码为:[\u4E00-\u9FA5]

范例:设置注册用户名程序,要求如下:

● 用户名必须是中文;

● 用户名长度为2~10;

import java.util.Scanner;

 

public class Te {

    public static void main(String args[]) {

        Scanner uname = new Scanner(System.in);

        System.out.print("请输入用户名:");

        String temp = uname.nextLine();

        boolean flag =true;

        System.out.println(

            temp.matches("[\u4E00-\u9FA5]{2,10}") ?(temp + ",欢迎使用") :"用户名格式错误");

    }

}

请输入用户名:

用户名格式错误

请输入用户名:hello

用户名格式错误

请输入用户名:吴力

吴力,欢迎使用

3、总结

1、正则可以方便的完成验证的操作,正则表达式是一组标准的规范,正则表达式是一组标准性的规范,在各个语言都可以使用。

2、String类对正则有所支持,这一点在以后的开发中将经常使用。

0 0