带你从零学大数据系列之Java篇---第十四章:正则表达式

课程重点:

  • 正则表达式简单理解
  • 正则表达式的简单使用

14.1. 正则表达式的简介

14.1.1. 正则表达式的简介

正则表达式, 不是Java特有的。 是一套独立的, 自成体系的知识点。 在很多语言中, 都有对正则的使用。

正则表达式, 使用来做字符串的校验、匹配的, 其实正则只有一个作用: 验证一个字符串是否与指定的规则匹配。

但是, 在很多的语言中, 都在匹配的基础上, 添加了其他的功能。 例如Java: 在匹配的基础上, 还添加了 删除、替换... 功能

14.1.2. 正则表达式的使用

实现相同的功能, 用String、StringBuffer、StringBuilder可以实现, 用正则表达式也可以实现。

但是在实现过程中, 复杂程度是完全不一样的。

/**
 * @Description
 */
public class Regex1 {

    public static void main(String[] args) {
        System.out.println(checkWithRegex("123456"));            // true
        System.out.println(checkWithRegex("1234"));              // false
        System.out.println(checkWithRegex("1234567890987"));     // false
        System.out.println(checkWithRegex("123.456"));           // false
        System.out.println(checkWithRegex("abcdefg"));           // false
        System.out.println(checkWithRegex("0123456"));           // false
    }

    /**
     * 使用正则表达式,验证一个字符串是否是一个合法的QQ号码
     * @param str 字符串
     * @return 验证的结果
     */
    private static boolean checkWithRegex(String str) {
        return str.matches("[1-9]\\d{5,10}");
    }

    /**
     * 验证一个字符串是否是一个合法的QQ号码
     * @param str 字符串
     * @return 验证的结果
     */
    private static boolean check(String str) {
        // 1. 校验长度
        if (str.length() < 6 || str.length() > 11) {
            return false;
        }
        // 2. 校验纯数字组成
        try {
            Long.parseLong(str);
        }
        catch (NumberFormatException e) {
            // 说明不是纯数字,无法转成long型的变量
            return false;
        }
        // 3. 首字符校验
        return str.charAt(0) != '0';
    }
}

14.2. 基本的元字符

14.2.1. 正则表达式的匹配规则

逐个字符进行匹配, 判断是否和正则表达式中定义的规则一致。

以下借助 String 类中的 matches 方法进行正则基础的语法讲解。

boolean matches(String regex);
是String类中的非静态方法, 使用字符串对象调用这个方法, 参数是一个正则表达式。
使用指定的正则表达式, 和当前的字符串进行匹配。 验证当前的字符串是否和指定的规则是相匹配的。

14.2.2. 元字符

14.2.3. 示例代码

/**
 * @Description 正则表达式的基础语法
 */
public class Regex2 {
    public static void main(String[] args) {
        // 校验规则:
        System.out.println(",ello".matches("[ahj1,8]ello"));
        System.out.println("fello".matches("[a-z]ello"));
        // 需求: 首位字符,可以是任意的小写字母,或者是 HAQ
        System.out.println("Hello".matches("[Ha-zAQ]ello"));
        // 需求: 首位字符,可以是任意的字母,包括大写字母和小写字母
        System.out.println("hello".matches("[a-zA-Z]ello"));
        // 需求: 首位字符,可以是除了h之外的任意字符
        System.out.println("Hello".matches("[^hel]ello"));
        // 需求: 首位字符,不可以是任意的小写字母,但是 h、e、q 除外
        System.out.println("lello".matches("[^a-z[heq]]ello"));

        // 希望首位字符,可以是 h e [
        System.out.println("]ello".matches("[he\\[]ello"));
        // 希望首位字符,可以是 a - z
        System.out.println("hello".matches("[az-]ello"));
        
        System.out.println("hello".matches("hel+o"));
        System.out.println("hello".matches("hel?o"));
        System.out.println("heo".matches("hel*o"));

        System.out.println("hello".matches("hel{3}o"));
        System.out.println("hello".matches("hel{3,}o"));
        System.out.println("hello".matches("hel{3,5}o"));
        
        // 需求: 匹配一个字符串可以是 126 或者是 163 或者是 qq 或者是 QQ
        System.out.println("123".matches("126|163|qq|QQ"));
        // 需求: 匹配一个qq邮箱、126邮箱、163邮箱
        System.out.println("admin@sina.com".matches("admin@(qq|126|163)\\.com"));
    }
}

14.3. String类中的常用的方法

14.3.1. 字符串的匹配

// QQ号的规则:
//      1. 纯数字组成的
//      2. 不能以0作为开头
//      3. 长度在 [6,11]
private static boolean chechQQ(String qqNumber) {
    return qqNumber.matches("[1-9]\\d{5,10}");
}

// 验证邮箱的合法性
//      1. 126
//      2. 前半部分可以是任意的单词字符, 长度限制在 [4,12]
//      3. 以.com作为结尾
private static boolean checkEmail(String email) {
    return email.matches("\\w{4,12}@126\\.com");
}

14.3.2. 字符串的切割

private static void split() {
    // 需求: 将一个存储有所有的姓名的字符串,切割出每一个名字。
    String names = "lily        lucy           polly      Jim       LiLei      HanMeimei";
    // 实现: 借助字符串的一个方法 split(String regex)
    //      将字符串中,满足正则规则的子部分,切割掉
    String[] nameArr = names.split(" +");
    System.out.println(Arrays.toString(nameArr));
}

14.3.3. 字符串的替换

private static void replace() {
    // 需求: 将这个存储有所有的名字的字符串,名字之间的分隔用, 来替代
    String names = "lily        lucy           polly      Jim       LiLei      HanMeimei";
    // 实现: 借助字符串中的一个方法 replaceAll(String regex, String replacement)
    //      将字符串中,满足指定正则的部分,替换成 replacement
    // String result = names.replaceAll(" +", ", ");
    String result = names.replaceFirst(" +", ", ");
    System.out.println(result);
}

private static void example() {
    // 需求: 将一个手机号的中间4位替换成 ****
    //      17788889999 => 177****9999
    String phoneNumber = "17788889999";
    // 在replace方法中,使用$1获取第一个分组的值
    String result = phoneNumber.replaceAll("(1\\d{2})(\\d{4})(\\d{4})", "$1****$3");
    System.out.println(result);
}

14.4. Pattern和Matcher类

14.4.1. 简介

在 java.util.regex 包中

Pattern类: 在Java中, 正则表达式的载体。 使用正则表达式进行字符串的校验、 切割、 替换, 都需要使用到这个类。

在Java中, 使用字符串的形式来写正则表达式。 此时, 如果需要这个字符串被当做是一个正则表达式使用, 必须先由这样的字符串, 编译为 Pattern 类的对象。 然后才可以使用这个对象的某些方法, 进行常见的操作(校验、切割、替换)。

Matcher类: 在Java中, 对一个正则校验的结果描述。

14.4.2. 常用方法

find()

从字符串的第0位开始查询, 查询是否有满足指定规则的子部分。

当再次调用find()的时候, 从上次查询到的位置开始, 继续向后查询。

关于查询

无论是 matches, 还是find, 还是lookingAt, 在字符串中进行校验、匹配的时候, 是有一个浮标存在的。

14.4.3. 示例代码

Pattern 类的使用:

/**
 * @Description Pattern类 和 Matcher类
 */
public class Regex1 {
    public static void main(String[] args) {
        // 1. 静态的校验
        boolean ret = Pattern.matches("[1-9]\\d{5,10}", "123456");
        System.out.println(ret);

        // 2. 将一个字符串编译为正则表达式对象(Pattern对象)
        Pattern pattern = Pattern.compile(" +");
        // 3. 字符串切割
        String[] array1 = pattern.split("Lily     Lucy    Polly     Jim     Tom");
        System.out.println(Arrays.toString(array1));

        String[] array2 = pattern.split("Lily     Lucy    Polly     Jim     Tom", 0);
        System.out.println(Arrays.toString(array2));
    }
}

Matcher:

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

/**
 * @Description Pattern和Matcher类的综合使用
 */
public class Regex2 {
    public static void main(String[] args) {
        // 1. 准备一个数据源
        String data = "abc123hello world456lily789lucy012uncle111wang";

        // 2. 将一个字符串变异成正则对象
        Pattern pattern = Pattern.compile("\\d+");

        // 3. 使用一个正则和一个字符串进行校验
        Matcher matcher = pattern.matcher(data);

        // 3.1. 获取整体校验的结果
        // 匹配逻辑:
        //      从第0个字符开始,判断每一个字符是否否则当前的正则。
        //      当找到了有不符合当前正则部分的时候,就会停止继续向后查找,直接返回false
        System.out.println(matcher.matches());

        // 3.2. find()
        while (matcher.find()) {
            System.out.print("匹配到了字符串: " + matcher.group() + ", ");
            System.out.println("下标范围: [" + matcher.start() + ", " + matcher.end() + ")");
        }

        // 3.3. lookingAt()
        System.out.println(matcher.lookingAt() + ", " + matcher.group() + ", [" + matcher.start() + ", " + matcher.end() + ")");
    }
}
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Description 每一个分组内容的获取
 */
public class Regex3 {
    public static void main(String[] args) {
        //
        Pattern pattern = Pattern.compile("(1\\d{2})(\\d{4})(\\d{4})");
        Matcher matcher = pattern.matcher("17788889999");

        // 获取分组的数量
        System.out.println(matcher.groupCount());
        // 获取每一个分组的值之前,先进行整体的匹配
        boolean ret = matcher.matches();
        // 获取到某一个分组的内容
        System.out.println(matcher.group(1));
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值