正则表达式(模式器,匹配器)及java中的日期表示

正则表达式

正则表达式:用于匹配某些特定字符串的一个规则。

没有学会使用正则表达式的时候,我们遇到过这么一个需求-----校验用户名是否合法?

具体要求如下:

1)用户名长度必须在6到15之间

2)必须是字母数字组合

非正则具体实现如下

public class Regex {
    public static void main(String[] args) {
        //1)用户名长度必须在6到15之间
        //2)必须是字母数字组合
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入用户名:");
        String s = sc.nextLine();
        if(s.length()>=6 && s.length()<=15){
            for (int i = 0; i < s.length(); i++) {
                char c = s.charAt(i);
                if((c>='A'&&c<='Z')||(c>='a'&&c<='z')||(c>='0'&&c<='9')){
                    System.out.println("用户名正确");
                    break;
                }else{
                    System.out.println("必须是字母数字组合");
                    break;
                }
            }
        }else{
            System.out.println("用户名长度必须在6到15之间");
        }
    }
}

看起来十分的繁琐,目前的要求只有两个,如果我们要在加一个并且用户名不能以0开头。就必须在原来基础上继续嵌套判断条件,这样显得程序十分雍容,当然不采用这种方式了。事实上这些需求在正则面前就显得弱爆了。请看正则表演:

正则具体实现如下

public class Regex {
    public static void main(String[] args) {
        //1)用户名长度必须在6到15之间
        //2)必须是字母数字组合
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入用户名:");
        String s = sc.nextLine();
        String regex = "[0-9A-Za-z]{6,15}";
        if (s.matches(regex)) {
            System.out.println("用户名合法");
        }else{
            System.out.println("用户名长度必须在6到15之间,必须是字母数字组合");
        }
    }
}

没错,实际校验的代码就两行,这就是正则表达式的强大之处。

我们来分析一下这里的正则表达式,[0-9A-Za-z]这里是一个组合的写法表示可以是0-9或者任意大小写字母的组合也可以写成预定义字符\\w也是表示0-9或者任意大小写字母的组合。

{6,15}这个是表示数量,具体就是这里的用户名的长度必须在6到15之间。

再来看一个需求

校验邮箱,要求邮箱的前缀名必须是4-12位的数字字母组合且不能以0开头

public class CheckEmail {
    public static void main(String[] args) {
        //前缀名必须是4-15位的数字字母组合且不能以0开头
        //定义正则表达式
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入你的邮箱:");
        String regex ="[1-9a-zA-Z][0-9a-zA-Z]{3,15}@[a-z1-9]{1,10}\\.(com|cn|net|org|edu)";
        String s = sc.nextLine();
        if(s.matches(regex)){
            System.out.println("邮箱格式正确");
        }else{
            System.out.println("邮箱格式不正确");
        }

    }
}

模式器(Pattern)和匹配器(Matcher)

模式器:用于封装正则表达式(某种特定规则的类)

匹配器:用于匹配模式器的类,该类提供了许多方法

API提供的调用顺序

Pattern p = Pattern.compile("a*b");
Matcher m = p.matcher("aaaaab");
boolean b = m.matches();

我们现在就来用模式器和匹配器改写刚才的校验邮箱的程序

public class CheckEmail {
    public static void main(String[] args) {
        //前缀名必须是4-15位的数字字母组合且不能以0开头
        //定义正则表达式
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入你的邮箱:");
        String regex ="[1-9a-zA-Z][0-9a-zA-Z]{3,15}@[a-z1-9]{1,10}\\.(com|cn|net|org|edu)";
        String s = sc.nextLine();
        Pattern p = Pattern.compile(regex); //获得模式器对象
        Matcher m = p.matcher(s);//获取匹配器对象
        boolean flag = m.matches();//校验
        if(flag){
            System.out.println("邮箱格式正确");
        }else{
            System.out.println("邮箱格式不正确");
        }

    }
}

疑问:之前我用过String类的matcher方法直接一下就可以实现了这个功能,为什么还要再定义一个模式器匹配器,岂不多此一举?

回答:在这个功能中是多余的,我只是举个例子,但是java给我提供这两个类肯定还有别的用处,这里只是简单的判断是否符合该正则表达式,但是如果一个需求中需要我们获取满足该正则表达式的字段,我们该如何获取呢,这下就需要使用Pattern和Matcher了,请看这个需求:

从这个字符串中找出所以由四个单词组成的字符序列

"wo ai bei jing tian an men, tian an men shang tai yang sheng"

 在写代码前,介绍一下Matcher类给我们提供的两个方法

public boolean find() 尝试查找与该模式匹配的输入序列的下一个子序列。结果返回true,反正false
public String group() 返回由以前匹配操作所匹配的输入子序列。
public class PMDemo {
    public static void main(String[] args) {
        String s = "wo ai bei jing tian an men, tian an men shang tai yang sheng";
        String regex = "[a-zA-Z]{4}";
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(s);
        while (m.find()) {
            System.out.println(m.group());
        }
    }
}

运行结果如下

jing
tian
tian
shan
yang
shen 

提问:需求实现了吗?

回答:实现了啊 !

再问:你确定,你在仔细看看,shan,shen 是什么东东?

回答:emm。。。。。

解答:这里存在一个单词边界的问题,需要区分单词开头和结尾,改进代码如下

public class PMDemo {
    public static void main(String[] args) {
        String s = "wo ai bei jing tian an men, tian an men shang tai yang sheng";
        String regex = "\\b[a-zA-Z]{4}\\b";
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(s);
        while (m.find()) {
            System.out.println(m.group());
        }
    }
}

 运行结果

jing
tian
tian
yang

 日期类

需求1:按格式输出现在的时间,例如(2018年10月29日 16:24:32 星期一)

public class DateDemo2 {
    public static void main(String[] args) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss E");
        String format = simpleDateFormat.format(new Date());
        System.out.println(format);
    }
}

运行结果:

2018年10月29日 17:09:04 星期一

需求2:任意输入一个年份,输出该年的二月有多少天?

提问:那你写个算法吧

回答:好吧!

public class FIndE {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个年份");
        int year =sc.nextInt();
        if((year%4==0&&year%100!=0)||year%400==0){
            System.out.println(year+"二月份有29天");
        }else
            System.out.println(year+"二月份有28天");
    }
}

请输入一个年份
2008
2008二月份有29天 

提问:实现了吧

回答:对呀,请看代码

再提问:请写出方法二

回答:emm。。。。(沉默)

解答:我们可以利用Calendar类中的方法获得该年份的三月的第一天,然后天数减一不就得到二月份的最后一天是几号了吗!这才叫面向对象思想,学着点。

public class FIndE {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个年份");
        int year =sc.nextInt();
        Calendar ins = Calendar.getInstance();//获取日期类对象
        ins.set(year,2,1);//注意:外国人写的方法每年十二个月表示是从0月到11月的,所以这里应该写2月
        ins.add(Calendar.DAY_OF_MONTH,-1);//三月一号减一
        System.out.println(year+"年二月份一共有"+ins.get(Calendar.DAY_OF_MONTH)+"天");//获得这一天在该月份中的第几天

    }
}

执行结果:

请输入一个年份
2018
2018年二月份一共有28天

需求3:输入一个日期,算一下那一天离今天多少天了

提问:如何将字符串类型转换为时间类型

解答:通过SimpleDateFormat类中的parse方法

public class SimpleDateFormatDemo {
    public static void main(String[] args) throws ParseException {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个日期 格式为2018年10月27日");
        String day = sc.nextLine();
        SimpleDateFormat smp = new SimpleDateFormat("yyyy年MM月dd日");
        Date date = smp.parse(day);
        long time = date.getTime();
        long now = System.currentTimeMillis();
        System.out.println(day+"与今天相距"+(now -time)/1000/60/60/24+"天");
    }
}

运行结果:1997年7月30日与今天相距7761天

猜你喜欢

转载自blog.csdn.net/qq_37291761/article/details/83506212
今日推荐