0

0

Java正则表达式:从混合字符串中高效提取数字序列

霞舞

霞舞

发布时间:2025-09-25 11:47:00

|

874人浏览过

|

来源于php中文网

原创

Java正则表达式:从混合字符串中高效提取数字序列

本文探讨了在Java中如何使用正则表达式从包含数字、字母和特殊字符的混合文本中提取数字序列。核心挑战在于,由非空白字符分隔的数字应被视为一个整体,而由空白字符分隔的数字则应视为独立的序列。文章详细介绍了两种基于Java 8及更高版本的解决方案:利用Matcher.results()配合特定正则表达式捕获数字块,以及通过Pattern.splitAsStream()按空白符分割后再处理。两种方法均结合Stream API进行高效的数据转换和提取,并提供了详细的代码示例。

引言

在数据处理和文本分析中,我们经常需要从复杂的字符串中提取特定的信息。一个常见的需求是从包含字母、数字和特殊字符的混合文本中识别并提取数字。然而,当需求变得更加精细时,例如要求将由非空白字符连接的数字视为一个连续的数字序列,而将由空白字符分隔的数字视为独立的序列,传统的正则表达式方法可能会显得力不从心。

例如,对于字符串 ds[44]%6c,我们期望提取 446。而对于 2021 ds[44]%6c,我们期望提取 2021 和 446。本教程将介绍两种基于Java的解决方案,利用正则表达式和Stream API高效地实现这一目标。

解决方案一:使用 Matcher.results() 捕获数字块 (Java 9+)

此方法通过构建一个能够捕获包含数字且两侧由零个或多个非空白字符包围的序列的正则表达式,然后利用Java 9引入的 Matcher.results() 方法来获取所有匹配项。

1. 正则表达式分析

我们将使用以下正则表达式:[^\\s]*\\d+[^\\s]*

  • [^\\s]*:匹配零个或多个非空白字符。这部分用于捕获数字左侧的非数字、非空白字符,确保它们与数字一起被视为一个整体。
  • \\d+:匹配一个或多个数字。这是我们想要提取的核心数字部分。
  • [^\\s]*:再次匹配零个或多个非空白字符。这部分用于捕获数字右侧的非数字、非空白字符,同样确保它们与数字一起被视为一个整体。

这个正则表达式的整体作用是捕获一个“块”,这个块中至少包含一个数字,并且整个块不包含任何空白字符。

立即学习Java免费学习笔记(深入)”;

2. 实现步骤

  1. 定义一个 Pattern 对象,编译上述正则表达式。
  2. 对输入字符串使用 Pattern.matcher() 创建 Matcher 对象。
  3. 调用 Matcher.results() 获取一个 Stream。每个 MatchResult 代表一个完整的匹配项。
  4. 通过 map(MatchResult::group) 提取每个匹配项的完整字符串。
  5. 对每个提取出的字符串,使用 replaceAll("\\D+", "") 移除所有非数字字符,只保留纯数字。
  6. 将纯数字字符串通过 map(Integer::valueOf) 转换为 Integer 类型。
  7. 最后,使用 toList() 将结果收集到一个 List 中。

3. 示例代码

import java.util.List;
import java.util.regex.MatchResult;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class NumberExtractor {

    // 定义一个正则表达式,用于捕获包含至少一个数字,且前后由零个或多个非空白字符包围的序列
    public static final Pattern TEXT_WITH_DIGITS = Pattern.compile("[^\\s]*\\d+[^\\s]*");

    /**
     * 从字符串中提取符合特定规则的数字序列。
     * 数字序列由非空白字符连接时被视为一个整体,由空白字符分隔时被视为独立序列。
     *
     * @param str 待处理的输入字符串
     * @return 提取出的数字序列列表
     */
    public static List getIntsUsingMatcherResults(String str) {
        return TEXT_WITH_DIGITS.matcher(str).results() // 获取所有匹配项的Stream
            .map(MatchResult::group)                   // 提取每个匹配项的完整字符串
            .map(s -> s.replaceAll("\\D+", ""))        // 移除字符串中的所有非数字字符
            .map(Integer::valueOf)                     // 将纯数字字符串转换为Integer
            .collect(Collectors.toList());             // 收集结果到List
    }

    // ... (后续将添加 main 方法和另一个解决方案)
}

4. 注意事项

  • 此方法需要 Java 9 或更高版本,因为 Matcher.results() 是 Java 9 中引入的。
  • 正则表达式 [^\\s]*\\d+[^\\s]* 确保了匹配到的块内部不会包含空白字符,从而满足了由非空白字符连接的数字视为一个整体的要求。

解决方案二:使用 Pattern.splitAsStream() 按空白符分割 (Java 8+)

此方法采取不同的策略:首先根据空白字符将整个字符串分割成多个子串,然后对每个子串进行处理以提取其中的数字。

10分钟内自己学会PHP
10分钟内自己学会PHP

10分钟内自己学会PHP其中,第1篇为入门篇,主要包括了解PHP、PHP开发环境搭建、PHP开发基础、PHP流程控制语句、函数、字符串操作、正则表达式、PHP数组、PHP与Web页面交互、日期和时间等内容;第2篇为提高篇,主要包括MySQL数据库设计、PHP操作MySQL数据库、Cookie和Session、图形图像处理技术、文件和目录处理技术、面向对象、PDO数据库抽象层、程序调试与错误处理、A

下载

1. 正则表达式分析

我们将使用以下正则表达式进行分割:\\s+

  • \\s+:匹配一个或多个空白字符。这将作为我们的分隔符,将字符串拆分成多个不含空白字符的片段。

2. 实现步骤

  1. 定义一个 Pattern 对象,编译正则表达式 \\s+。
  2. 对输入字符串调用 Pattern.splitAsStream(str),这将生成一个 Stream,其中每个元素都是按空白符分割后的子串。
  3. 处理起始空白符的边缘情况:如果输入字符串以空白符开头,splitAsStream() 会在Stream的第一个位置生成一个空字符串。为了避免这种情况,我们使用 dropWhile(String::isEmpty) 来跳过所有开头的空字符串。
  4. 对每个子串,使用 replaceAll("\\D+", "") 移除所有非数字字符。
  5. 将纯数字字符串通过 map(Integer::valueOf) 转换为 Integer 类型。
  6. 最后,使用 toList() 将结果收集到一个 List 中。

3. 示例代码

import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

// ... (NumberExtractor 类的其他部分)

public class NumberExtractor {

    // ... (getIntsUsingMatcherResults 方法)

    // 定义一个正则表达式,用于匹配一个或多个空白字符,作为分割符
    public static final Pattern WHITE_SPACES = Pattern.compile("\\s+");

    /**
     * 从字符串中提取符合特定规则的数字序列。
     * 该方法首先按空白符分割字符串,然后从每个片段中提取数字。
     *
     * @param str 待处理的输入字符串
     * @return 提取出的数字序列列表
     */
    public static List getIntsUsingSplitAsStream(String str) {
        return WHITE_SPACES.splitAsStream(str)      // 按空白符分割字符串,生成Stream
            .dropWhile(String::isEmpty)             // 跳过开头的空字符串(如果存在,例如字符串以空白符开头)
            .map(s -> s.replaceAll("\\D+", ""))    // 移除每个片段中的所有非数字字符
            .map(Integer::valueOf)                  // 将纯数字字符串转换为Integer
            .collect(Collectors.toList());         // 收集结果到List
    }

    public static void main(String[] args) {
        System.out.println("--- 使用 Matcher.results() ---");
        System.out.println("ds[44]%6c -> " + getIntsUsingMatcherResults("ds[44]%6c"));
        System.out.println("2021 ds[44]%6c -> " + getIntsUsingMatcherResults("2021 ds[44]%6c"));
        System.out.println("  abc 123 def 456   -> " + getIntsUsingMatcherResults("  abc 123 def 456   "));
        System.out.println("no_digits_here -> " + getIntsUsingMatcherResults("no_digits_here"));
        System.out.println("only_42 -> " + getIntsUsingMatcherResults("only_42"));
        System.out.println("mixed123_456_chars -> " + getIntsUsingMatcherResults("mixed123_456_chars"));


        System.out.println("\n--- 使用 Pattern.splitAsStream() ---");
        System.out.println("ds[44]%6c -> " + getIntsUsingSplitAsStream("ds[44]%6c"));
        System.out.println("2021 ds[44]%6c -> " + getIntsUsingSplitAsStream("2021 ds[44]%6c"));
        System.out.println("  abc 123 def 456   -> " + getIntsUsingSplitAsStream("  abc 123 def 456   "));
        System.out.println("no_digits_here -> " + getIntsUsingSplitAsStream("no_digits_here"));
        System.out.println("only_42 -> " + getIntsUsingSplitAsStream("only_42"));
        System.out.println("mixed123_456_chars -> " + getIntsUsingSplitAsStream("mixed123_456_chars"));
    }
}

4. 注意事项

  • 此方法需要 Java 8 或更高版本,因为 Pattern.splitAsStream() 和 Stream.dropWhile() (Java 9+) 或其他Stream操作是 Java 8/9 中引入的。dropWhile本身是Java 9引入,如果要在Java 8中使用,需要手动过滤空字符串,例如 filter(s -> !s.isEmpty())。
  • Pattern.splitAsStream() 相较于 String.split() 的优势在于,它直接生成一个Stream,避免了创建中间数组的开销,对于处理大型字符串时可能更高效。

运行结果

执行上述 main 方法,将得到如下输出:

--- 使用 Matcher.results() ---
ds[44]%6c -> [446]
2021 ds[44]%6c -> [2021, 446]
  abc 123 def 456   -> [123, 456]
no_digits_here -> []
only_42 -> [42]
mixed123_456_chars -> [123456]

--- 使用 Pattern.splitAsStream() ---
ds[44]%6c -> [446]
2021 ds[44]%6c -> [2021, 446]
  abc 123 def 456   -> [123, 456]
no_digits_here -> []
only_42 -> [42]
mixed123_456_chars -> [123456]

可以看到,两种方法都成功地实现了预期的数字提取逻辑。

总结

本文详细介绍了在Java中利用正则表达式和Stream API从混合字符串中提取特定数字序列的两种有效方法。

  • Matcher.results() 方法 (Java 9+):通过一个精巧的正则表达式 [^\\s]*\\d+[^\\s]* 直接匹配不含空白字符的数字块,然后通过Stream操作清理非数字字符并转换为整数。这种方法在概念上更直接,因为它一次性捕获了符合条件的“数字单元”。
  • Pattern.splitAsStream() 方法 (Java 8+):首先利用 \\s+ 正则表达式按空白符将字符串分割成多个片段,然后对每个片段进行数字提取和转换。此方法在处理以空白符开头的字符串时需要额外的 dropWhile (或 filter) 处理。

选择哪种方法取决于您的Java版本偏好以及对代码可读性的考量。两者都能高效地解决将由非空白字符连接的数字视为一个整体,而由空白字符分隔的数字视为独立序列的问题。在实际应用中,应根据具体场景和性能要求选择最合适的方案。

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

825

2023.06.15

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

724

2023.07.05

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

728

2023.07.31

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

395

2023.08.01

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

398

2023.08.02

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

445

2023.08.02

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

428

2023.08.02

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

16881

2023.08.03

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 2.1万人学习

C# 教程
C# 教程

共94课时 | 5.7万人学习

Java 教程
Java 教程

共578课时 | 40万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号