在Java开发中,文本读取、字符串处理、正则匹配是日常开发最频繁的操作。绝大多数业务场景,比如参数校验、文本解析、日志提取、用户输入处理,都离不开四个核心类:

  • String:字符串存储与基础操作核心类

  • Scanner:流式数据扫描器,用于读取输入、解析文本

  • Pattern:正则表达式编译类,定义匹配规则

  • Matcher:正则匹配执行类,实现查找、匹配、替换

一、String 类:字符串核心处理类

1. 核心特性(面试高频)

String 是 不可变字符串,被 final 修饰,底层存储为字符数组(JDK9+ 改为字节数组)。每次对 String 进行修改(拼接、截取、替换),都会生成新字符串,原字符串不会改变。

优势:线程安全、字符串常量池复用、哈希值不可变;劣势:频繁修改效率低(推荐 StringBuilder/StringBuffer)。

2. 高频常用方法

涵盖开发90%字符串场景:判断、截取、替换、分割、转换、去空

  • 判断:equals()、isEmpty()、contains()、startsWith()、endsWith()

  • 截取:substring()、charAt()

  • 修改:replace()、trim()、toLowerCase()、toUpperCase()

  • 分割:split()

  • 转换:valueOf()、getBytes()、toCharArray()

3. String 完整实战代码

/**
 * String 类常用方法实战
 */
public class StringDemo {
    public static void main(String[] args) {
        String str = "  Hello Java Text  ";

        // 1. 去首尾空格
        String trimStr = str.trim();
        System.out.println("去空格:" + trimStr); // Hello Java Text

        // 2. 判断是否为空、包含字符、首尾匹配
        System.out.println("是否为空:" + str.isEmpty()); // false
        System.out.println("是否包含Java:" + trimStr.contains("Java")); // true
        System.out.println("是否以Hello开头:" + trimStr.startsWith("Hello")); // true
        System.out.println("是否以Text结尾:" + trimStr.endsWith("Text")); // true

        // 3. 字符串截取
        System.out.println("截取前5位:" + trimStr.substring(0, 5)); // Hello
        System.out.println("获取下标6字符:" + trimStr.charAt(6)); // J

        // 4. 字符串替换
        String replaceStr = trimStr.replace("Java", "Java正则");
        System.out.println("替换后:" + replaceStr); // Hello Java正则 Text

        // 5. 字符串分割
        String[] splitArr = trimStr.split(" ");
        System.out.println("分割结果:");
        for (String s : splitArr) {
            System.out.println(s);
        }

        // 6. 大小写转换
        System.out.println("大写:" + trimStr.toUpperCase());
        System.out.println("小写:" + trimStr.toLowerCase());

        // 7. 类型转换
        int num = 123;
        String numStr = String.valueOf(num); // 数字转字符串
        System.out.println("数字转字符串:" + numStr);
    }
}

二、Scanner 类:文本/输入扫描解析器

Scanner 是 Java 提供的流式扫描工具,核心作用是:读取控制台输入、读取文件文本、按规则分割解析字符串,相比 BufferedReader,用法更简单,适合轻量级文本解析。

1. 核心常用方法

  • next():读取单个字符串(空格/换行截断)

  • nextLine():读取整行字符串(包含空格,换行截断)

  • nextInt()/nextDouble():读取指定类型数据

  • useDelimiter():自定义分隔符(核心高级用法)

  • hasNext():判断是否还有下一个数据

2. 避坑重点

nextInt() 和 nextLine() 混用bug:nextInt() 只会读取数字,会残留换行符,导致后续 nextLine() 直接读取空值。解决方案:读取数字后手动吸收换行符。

3. Scanner 完整实战代码

import java.util.Scanner;

/**
 * Scanner 类实战:控制台输入 + 自定义文本解析
 */
public class ScannerDemo {
    public static void main(String[] args) {
        // 1. 基础控制台输入
        Scanner scanner = new Scanner(System.in);

        System.out.print("请输入姓名:");
        String name = scanner.nextLine();

        System.out.print("请输入年龄:");
        // 解决混用bug:读取数字后吸收换行
        int age = scanner.nextInt();
        scanner.nextLine(); 

        System.out.println("姓名:" + name + ",年龄:" + age);

        // 2. 高级用法:自定义分隔符解析字符串
        String text = "张三,20,男;李四,22,女;王五,21,男";
        Scanner textScanner = new Scanner(text);
        // 自定义分隔符:逗号、分号
        textScanner.useDelimiter("[,;]");

        System.out.println("\n=====自定义分隔符解析文本=====");
        while (textScanner.hasNext()) {
            System.out.print(textScanner.next() + "\t");
        }

        // 关闭流
        scanner.close();
        textScanner.close();
    }
}

三、Pattern + Matcher 类:Java正则核心

很多新手直接用 String 的 split()、replaceAll() 做正则匹配,底层其实都是调用了 Pattern 和 Matcher。

核心关系

  • Pattern:正则规则编译类,将正则字符串编译成匹配模板(可复用,性能更高)

  • Matcher:匹配执行器,绑定文本和Pattern,实现精准匹配、查找、分组、替换

适用场景:复杂文本提取、手机号/邮箱/身份证校验、日志关键字提取、批量文本替换。

1. 核心方法说明

Pattern 核心方法
  • compile(String regex):编译正则表达式

  • matcher(CharSequence input):创建匹配器

  • matches():全局匹配(整个文本是否符合规则)

Matcher 核心方法
  • matches():全局匹配

  • find():查找下一个匹配的子串

  • group():获取匹配结果,支持分组获取

  • replaceAll():全局替换匹配内容

2. Pattern + Matcher 完整实战代码

包含:手机号校验、分组提取、关键字替换、批量查找四大高频场景

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

/**
 * Pattern + Matcher 正则实战
 * 场景:手机号校验、分组提取、文本替换、关键字查找
 */
public class PatternMatcherDemo {
    public static void main(String[] args) {
        // 正则1:国内手机号正则
        String phoneRegex = "^1[3-9]\\d{9}$";
        // 正则2:提取文本中的数字
        String numRegex = "\\d+";
        // 正则3:匹配邮箱
        String emailRegex = "\\w+@\\w+\\.\\w+";

        // 1. 全局匹配:手机号校验
        Pattern phonePattern = Pattern.compile(phoneRegex);
        String phone1 = "13812345678";
        String phone2 = "12345678901";
        System.out.println("手机号1是否合法:" + phonePattern.matcher(phone1).matches()); // true
        System.out.println("手机号2是否合法:" + phonePattern.matcher(phone2).matches()); // false

        // 2. 批量查找:提取文本中所有数字
        String content = "订单号:20260619,金额:99.9元,数量:5件";
        Pattern numPattern = Pattern.compile(numRegex);
        Matcher numMatcher = numPattern.matcher(content);

        System.out.println("\n=====提取文本中所有数字=====");
        while (numMatcher.find()) {
            System.out.println("匹配到数字:" + numMatcher.group());
        }

        // 3. 分组匹配:提取用户名和邮箱后缀
        String emailContent = "测试邮箱:test123@qq.com,工作邮箱:java@163.com";
        Pattern emailPattern = Pattern.compile("(\\w+)@(\\w+\\.\\w+)");
        Matcher emailMatcher = emailPattern.matcher(emailContent);

        System.out.println("\n=====邮箱分组提取=====");
        while (emailMatcher.find()) {
            // group(1):第一组内容(用户名),group(2):第二组内容(域名)
            System.out.println("用户名:" + emailMatcher.group(1) + ",域名:" + emailMatcher.group(2));
        }

        // 4. 正则替换:脱敏手机号
        String userPhone = "用户手机号:13812345678";
        String desensitize = phonePattern.matcher(userPhone).replaceAll("138****5678");
        System.out.println("\n手机号脱敏结果:" + desensitize);
    }
}

四、四大类综合实战:文本解析工具

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

/**
 * 综合实战:文本数据解析与校验工具
 */
public class TextAllDemo {
    public static void main(String[] args) {
        // 原始文本数据
        String data = "用户:小明,电话:13966668888,邮箱:xiaoming@163.com;\n" +
                      "用户:小红,电话:12345678901,邮箱:xiaohong@qq.com";

        // 1. Scanner解析每行数据
        Scanner scanner = new Scanner(data);
        String phoneRegex = "^1[3-9]\\d{9}$";
        Pattern pattern = Pattern.compile(phoneRegex);

        while (scanner.hasNextLine()) {
            String line = scanner.nextLine().trim();
            // 截取手机号片段
            String phone = line.split("电话:")[1].split(",")[0];
            // 正则校验
            Matcher matcher = pattern.matcher(phone);
            if (matcher.matches()) {
                System.out.println("合法用户数据:" + line);
            } else {
                System.out.println("非法手机号,数据过滤:" + line);
            }
        }
        scanner.close();
    }
}

五、核心总结与开发建议

1. 各类使用场景选择

  • 简单字符串操作:优先使用 String 自带方法(简洁高效)

  • 读取控制台/自定义文本解析:使用 Scanner(轻量易用)

  • 复杂正则匹配、分组提取、批量解析:必须用 Pattern + Matcher(性能远优于 String 正则方法)

2. 性能优化要点

  • Pattern 支持复用,不要在循环内重复 compile,避免频繁创建对象

  • 大量字符串拼接,禁止直接用 +,使用 StringBuilder

  • Scanner 使用完毕必须关闭,避免IO资源泄漏

3. 常见避坑

  • String 不可变,修改操作必生成新对象

  • Scanner nextInt/nextLine 混用残留换行符问题

  • 正则匹配区分 全局匹配(matches)局部查找(find)

Logo

CANN开发者社区旨在汇聚广大开发者,围绕CANN架构重构、算子开发、部署应用优化等核心方向,展开深度交流与思想碰撞,携手共同促进CANN开放生态突破!

更多推荐