Java 实例 – 字符串查找(快速上手)

Java 实例 – 字符串查找:从入门到实战

在日常开发中,字符串操作是 Java 编程中最常见的任务之一。无论你是处理用户输入、解析日志文件,还是做文本分析,字符串查找几乎无处不在。今天我们就来深入探讨 Java 中的字符串查找机制,通过一个个真实可运行的实例,带你从基础用法到高级技巧,全面掌握这一核心技能。

想象一下,你在一本厚厚的字典里找一个词。如果从头开始逐页翻找,效率很低。但如果你知道这个词大概在哪个区域,或者有索引帮助定位,查找就会快得多。字符串查找在 Java 中也是一样——合理使用内置方法,能让你的程序如虎添翼。


基础方法:indexOf 与 lastIndexOf

Java 提供了两个最基础的字符串查找方法:indexOflastIndexOf。它们分别用于查找第一个匹配项和最后一个匹配项的位置。

indexOf:从左到右找

indexOf 方法返回指定子串在原字符串中第一次出现的位置(从 0 开始计数),如果没找到则返回 -1。

public class StringSearchExample {
    public static void main(String[] args) {
        String text = "Java 8 是一个重要的版本,Java 11 更是性能飞跃。";
        
        // 查找第一个 "Java" 出现的位置
        int firstIndex = text.indexOf("Java");
        System.out.println("第一个 'Java' 出现在位置: " + firstIndex); // 输出: 0
        
        // 查找 "11" 出现的位置
        int secondIndex = text.indexOf("11");
        System.out.println("第一个 '11' 出现在位置: " + secondIndex); // 输出: 26
    }
}

注释说明

  • indexOf("Java") 从字符串开头开始搜索,找到第一个匹配项的位置。
  • 如果子串不存在,返回 -1,这是判断查找是否成功的标准方式。
  • 位置从 0 开始,因此第一个字符在位置 0。

lastIndexOf:从右到左找

lastIndexOfindexOf 类似,但它是从字符串末尾向前查找,返回最后一个匹配项的位置。

public class LastIndexOfExample {
    public static void main(String[] args) {
        String text = "Java 8 是一个重要的版本,Java 11 更是性能飞跃。";
        
        // 查找最后一个 "Java" 出现的位置
        int lastIndex = text.lastIndexOf("Java");
        System.out.println("最后一个 'Java' 出现在位置: " + lastIndex); // 输出: 22
    }
}

注释说明

  • 虽然 "Java" 出现了两次(位置 0 和 22),lastIndexOf 返回的是最后一次出现的位置。
  • 适用于需要从后往前处理文本的场景,比如提取文件名中的扩展名。

高级查找:contains 与 startsWith / endsWith

除了查找位置,我们还常需要判断字符串是否包含某个子串,或者是否以某个模式开头/结尾。

contains:判断是否包含

contains 方法是 indexOf 的简化封装,直接返回布尔值,判断子串是否存在。

public class ContainsExample {
    public static void main(String[] args) {
        String email = "user@example.com";
        
        // 判断邮箱是否包含 '@'
        boolean hasAt = email.contains("@");
        System.out.println("邮箱是否包含 '@': " + hasAt); // 输出: true
        
        // 判断是否包含 "example"
        boolean hasExample = email.contains("example");
        System.out.println("邮箱是否包含 'example': " + hasExample); // 输出: true
    }
}

注释说明

  • contains 内部调用 indexOf,如果返回值不为 -1,就认为存在。
  • 适合用于条件判断,代码更直观,可读性更强。

startsWith 与 endsWith:前后缀判断

这两个方法用于判断字符串是否以指定前缀或后缀开头/结尾,常用于路径、文件类型判断。

public class PrefixSuffixExample {
    public static void main(String[] args) {
        String fileName = "report.pdf";
        String path = "/home/user/documents/notes.txt";
        
        // 判断文件是否为 PDF
        boolean isPdf = fileName.endsWith(".pdf");
        System.out.println("文件是否为 PDF: " + isPdf); // 输出: true
        
        // 判断路径是否以 "documents" 结尾
        boolean isDocuments = path.endsWith("documents");
        System.out.println("路径是否以 'documents' 结尾: " + isDocuments); // 输出: false
        
        // 判断路径是否以 "/" 开头
        boolean isRoot = path.startsWith("/");
        System.out.println("路径是否以 '/' 开头: " + isRoot); // 输出: true
    }
}

注释说明

  • endsWith 常用于判断文件扩展名,比如 .jpg, .json 等。
  • startsWith 常用于路径处理或协议判断,如 http://, https://

多次查找:循环遍历所有匹配项

有时我们需要找出字符串中所有匹配子串的位置。indexOf 支持从指定位置开始搜索,这为我们实现“多次查找”提供了可能。

public class MultipleFindExample {
    public static void main(String[] args) {
        String text = "Java 是一门编程语言,Java 8 引入了 Lambda,Java 11 又有新特性。";
        String target = "Java";
        
        int index = 0;
        int count = 0;
        
        // 循环查找所有 "Java" 的位置
        while ((index = text.indexOf(target, index)) != -1) {
            count++;
            System.out.println("第 " + count + " 次找到 'Java',位置: " + index);
            index += target.length(); // 从下一个位置继续查找
        }
    }
}

注释说明

  • indexOf(target, index) 表示从第 index 个字符开始查找。
  • 每次找到后,将 index 增加 target.length(),避免重复匹配同一个位置。
  • 这种写法是 Java 中实现“全量查找”的标准模式。

正则表达式查找:Pattern 与 Matcher

当查找需求更复杂时,比如匹配数字、邮箱格式、日期等,正则表达式就派上用场了。

使用正则匹配所有数字

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

public class RegexFindExample {
    public static void main(String[] args) {
        String text = "用户ID: 12345,订单号: 67890,金额: 99.99元";
        
        // 定义正则:匹配一个或多个数字
        Pattern pattern = Pattern.compile("\\d+");
        Matcher matcher = pattern.matcher(text);
        
        int count = 0;
        while (matcher.find()) {
            count++;
            System.out.println("第 " + count + " 个数字: " + matcher.group());
        }
    }
}

注释说明

  • \\d+ 是正则表达式,表示“一个或多个数字”。
  • Pattern.compile() 编译正则表达式,提高效率。
  • matcher.find() 逐个匹配,group() 返回实际匹配的字符串。
  • 适用于日志解析、数据抽取等场景。

实际应用:文本关键词高亮

我们来做一个小实战:给一段文本中的关键词添加高亮标签。

public class KeywordHighlighter {
    public static void main(String[] args) {
        String content = "Java 8 引入了 Lambda 表达式,Java 11 支持了新的文本块。";
        String keyword = "Java";
        
        // 将关键词替换为带标签的高亮版本
        String highlighted = content.replace(keyword, "<strong>" + keyword + "</strong>");
        System.out.println("高亮后内容: " + highlighted);
        // 输出: <strong>Java</strong> 8 引入了 Lambda 表达式,<strong>Java</strong> 11 支持了新的文本块。
    }
}

注释说明

  • replace 是最简单的替换方式,适合关键词不多的情况。
  • 如果关键词可能有重叠或复杂匹配,建议使用正则表达式 replaceAll 配合 Pattern.quote() 防止特殊字符干扰。
  • 该技术广泛应用于搜索引擎结果、文档编辑器、内容管理系统。

总结与建议

通过本篇内容,我们系统学习了 Java 实例 – 字符串查找的多种方式:

  • 基础查找使用 indexOflastIndexOf,适合定位单个或最后匹配项。
  • 简单判断用 containsstartsWithendsWith,代码简洁易懂。
  • 多次查找时,结合 indexOf 的起始位置参数实现循环。
  • 复杂模式使用正则表达式,功能强大但需谨慎处理。
  • 实际项目中,合理选择方法能显著提升代码质量和可维护性。

记住,字符串查找不是“查到就行”,而是要“查得准、查得快、查得对”。从今天起,把查找技巧融入你的日常编码习惯中,你会发现 Java 的字符串处理能力远比想象中强大。

在实际开发中,多练习这些方法,结合真实项目场景,才能真正掌握 Java 实例 – 字符串查找的精髓。祝你编码愉快,写出更优雅的代码!