Java之正则表达式

语法

中文版

请点击这里

原版

请点击这里

多做练习是学习知识的最快途径

例题

持续更新,欢迎在评论区push。
以下练习部分转载自这里

练习:判断号码是否合法有效

对输入的qq号进行匹配(qq匹配规则:长度为5-10位,纯数字组成,且不能以0开头。)

没有学习正则表示式之前,我们需要用各种if语句来进行判断,但现在我们可以使用则正表达式的规则来操作:

package RegularExpression;

public class regexTest {
    public static void main(String[] args) {
        //测试:
        String qq1 = "1832137835";
        String qq2 = "789j9371";
        String qq3 = "22";
        String qq4 = "012189783";
        boolean b1 = isQQ(qq1);
        boolean b2 = isQQ(qq2);
        boolean b3 = isQQ(qq3);
        boolean b4 = isQQ(qq4);
        
        System.out.println(qq1+"是qq号码吗?"+b1);
        System.out.println(qq2+"是qq号码吗?"+b2);
        System.out.println(qq3+"是qq号码吗?"+b3);
        System.out.println(qq4+"是qq号码吗?"+b4);
    }
    
    //练习1:匹配QQ号(长度为5-10位,纯数字组成,且不能以0开头)
    public static boolean isQQ(String qq) {
        //定义匹配规则:
        String regex = "[1-9][0-9]{4,9}";
        
        //判断是否符合规则
        boolean b = qq.matches(regex);
        
        return b;
    }
}

运行结果:

解析:注意匹配规则被“浓缩”到了字符串regex中,我们只需要用"[1-9][0-9]{4,9}"就描述了qq的匹配规则,怎么做到的呢?
首先我们在匹配需要“一位一位地匹配”,qq匹配规则是第一位不能是0的纯数字,所以我们用[1-9]来表示第一位的规则;接下来是第二位:随意的数字都行,所以我们用[0-9]来表示,按照这个逻辑,当然后面的都应该是纯数字即[0-9],但我们需要确定qq的长度只能是5~10,而规则里我们用{}来表示范围,即[0-9]{4,9}结合起来就表示:4 ~ 9个纯数字。
  总的来说就是:[1 - 9]规定第一位只能是1~9即不为0的纯数字,而[0-9]{4,9}则规定可输入4 ~ 9个纯数字,加起来刚好是:首位不为0的长度为5~10的纯数字。
  上面使用的规则如[]、{}等特殊符号在标题二中都能找到,对于这些常用的符号我们记住就好。
  除了用[0-9]表示纯数字还可以用\d来表示(上面规则里有可以往上look),所以我们还可以令regex = “1[378]\d{9}”。(在java中\需要用\来转义,所以写为\d而不是\d)。

练习:字符串的切割

对字符串进行切割就是对一个字符串按照某个或某些字符进行切割,从而变成若干字符串。如“张三、李四、王五”,我们如果按照“、”来切割就变成三个字符串:“张三”,“李四”,“王五”。(切割的实质其实就是先进行字符串匹配,将匹配到的字符串“丢弃”,并将丢掉的前面部分和剩下的部分变成字符串)。

1:对字符串“张三@@@李四@@王五@茅台”进行切割,去掉@符号。

分析:首先我们要去掉字符串中的若干个@符号,如果只有一个@符号我们可以用直接用@来匹配,但这里的@是不确定的,所以我们要用到规则中的:

所以我们用@+来表示:@这个符号至少出现一次这种情况,现在我们可以来看看具体的代码:

package RegularExpression;

public class splitTest {
    public static void main(String[] args) {
        //练习1:切割字符串"张三@@@李四@@王五@茅台".
        String s = "张三@@@李四@@王五@茅台";
        
        //描述切割规则:以若干@来切割
        String regex = "@+";
        
        //切割后的字符串数组:
        String[] ss = s.split(regex);
        
        for(String string:ss){
            System.out.println(string);
        }
        
    }
}

打印结果:

2:【以叠词切割】:如字符串"abccsasahhhz"按“叠词”来切割就变成了“ab”,“sasa”,“z”。因为“cc”、“hhh”都是叠词,需要切割掉。现在请将字符串“张三@@@李四¥¥王五ssssssss江流儿”按照叠词切割。

分析:关键点在于如何表示叠词呢?连续出现两个以上的相同字符即为叠词,首先我们要表示任意字符:

   我们使用“.”来表示任意字符,接着我们需要表示两个这样的字符:这里我们需要使用到“组”的概念:
即使用括号:()来表示组,那么组是干嘛的?我们就可以 对组中的数据进行引用:那么regex = "(.)\1"就表示:某一字符出现了两次(注意首先我们用(.)来表示任意字符,而\1是对组(.)中的字符进行复用,合起来就是:两个相同的字符),现在我们不只是需要出现两次的字符,所以使用+号来表示出现多次,最终叠词就表示为:regex = “(.)\1+”。

看具体实现代码:

package RegularExpression;

public class splitTest {
    public static void main(String[] args) {
        //练习2:"张三@@@李四¥¥王五ssssssss江流儿"按叠词切割.
        String s = "张三@@@李四¥¥王五ssssssss江流儿";
        
        //叠词切割
        String regex = "(.)\\1+";
        
        //切割后的字符串数组:
        String[] ss = s.split(regex);
        
        for(String string:ss){
            System.out.println(string);
        }
        
    }
}

切割结果:

[一个小细节]:转义字符的使用
对于“haha.lisi.nihao”这样的字符串如果要用".“来切割,要怎么办呢?可能你会说定义regex=”."不就哦了吗?但是如果你代码真这样写的话,你的输出结果就会像你的脑海一样“一片空白”。注意:“.”这个符号在正则表达式中是有特殊意义的:
在这里插入图片描述
  这个小点可以代表任何字符,所以我们需要用转义字符\来将“.”转义为普通的点,所以只要把regex = "\\."即可。

练习:字符串替换

利用正则表达式进行字符串替换其实是先匹配指定字符串中的字符,然后再用自定义字符替换掉匹配到的字符串。

1、将字符串“张三@@@李四YYY王五*******王尼玛”中的叠词替换为:“、”。

分析:第一步是匹配叠词:上面的练习中我们已经知道regex = "(.)\1+"可以表示叠词,所以第二部就可以使用replaceAll()方法进行替换了:

package RegularExpression;

public class replaceAllTest {
    public static void main(String[] args) {
        //练习1:将字符串“张三@@@李四YYY王五*****王尼玛”中的叠词替换为:“、”。
        String str = "张三@@@李四YYY王五*****王尼玛";
        
        //匹配规则
        String regex = "(.)\\1+";
        
        //替换为:
        String newStr = str.replaceAll(regex, "、");
        
        //替换后结果:
        System.out.println(newStr);
    }
    
}

在这里插入图片描述
2、将“张三@@@李四YYY王五*******王尼玛”中的叠词替换为单字符,即结果为:“张三@李四Y王五*王尼玛”。

分析:这个练习和练习1很像,首先我们都需要匹配到叠词,但是替换的内容却不是固定的“、”了,我们需要将叠词替换为它本身的字符,所以我们需要引用组的内容,我们可以使用$1来复用组中第1组的值(即叠词的字符):

package RegularExpression;

public class replaceAllTest {
    public static void main(String[] args) {
        //练习2:将“张三@@@李四YYY王五*****王尼玛”中的叠词替换为单字符,即结果为:“张三@李四Y王五*王尼玛”。
        String str = "张三@@@李四YYY王五*****王尼玛";
        
        //匹配规则
        String regex = "(.)\\1+";
        
        //替换为:
        String newStr = str.replaceAll(regex, "$1");
        
        //替换后结果:
        System.out.println(newStr);
    }
    
}

在这里插入图片描述

练习:字符串获取

正则表达式其实是封装成了Pattern类,所以字符串的匹配、切割、替换都是调用了Pattern类中的方法。所以如果我们需要获取指定字符串中的子串,首先同样的我们需要进行字符串匹配,然后判断指定字符串中是否有匹配的子串,有就获取,没有就获取不到。

获取子串的步骤:

1、描述要获取的子串:匹配子串

2、使用正则表达式的封装类Pattern来获取匹配器

3、使用匹配器中的方法group()获取字符串的匹配的子串

获取字符串“Hi ! Don’t be moved by yourself Fzz”中为两个字母的单词。即Hi、be、by。

分析:根据上面的步骤:
第一步,我们要对子串进行匹配,即两个字母的单词,字母可以用[a-zA-Z]来表示,范围是两个,所以regex = “[a-zA-Z]{2}”。
但这样不够准确,我们需要的是单词,而不是三个字母,所以要用到“边界匹配器”,即在这里插入图片描述
单词边界:\b,所以regex = “\b[a-zA-Z]{2}\b”。
然后是第二步:获取匹配器
1 Pattern p = Pattern.compile(regex);
2 Matcher m = p.matcher(s);
最后一步:使用匹配器来获取匹配到的字符串
1 while(m.find()){
2 System.out.println(m.group());
3 }

我们来看看总体的实现代码:

package RegularExpression;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class groupTest {
    public static void main(String[] args) {
        String s = "Hi ! Don't be moved by yourself Fzz";
        
        //1、匹配子串
        String regex = "\\b[a-zA-Z]{2}\\b";
        
        //2、获取匹配器
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(s);
        
        //3、使用匹配器的group()方法来获取:(find方法是判断是否具有匹配子串)、
        System.out.println("”"+s+"“中的两个字母的单词有:");
        while(m.find()){
            System.out.println(m.group());
        }
    }
}

综合练习

1、口吃怎么办?需求:请将下面的字符串“我我我……我我……爱…爱爱……学…学……学编程”改为:“我爱学编程”。

分析:首先我们可以将字符串中的“……”去掉,然后就可以将叠词替换为单个汉字即可。

package RegularExpression;

public class test {
    public static void main(String[] args) {
        //口吃怎么办?将“我我我……我我……爱…爱爱……学…学……学编程”改为“我爱学编程”。
        String str = "我我我......我我......爱...爱爱...学...学......学编程";
        //1、首先去掉...(将.替换为""即可)
        String regex = "\\.";
        String str1 = str.replaceAll(regex,"");
        System.out.println("1:"+str1);
        //2、替代叠词
        regex = "(.)\\1+";
        String str2 = str1.replaceAll(regex, "$1");
        System.out.println("2:"+str2);
    }
}

总结

正则表达式还有很多规则需要我们去深入学习,对于正则表达式,它的优点就是简化了字符串的操作,缺点是我们需要学习这些特点的规则,而且符号过多时不方便阅读。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值