0

0

Java中利用正则表达式和Stream API从混合字符串中高效提取数字

花韻仙語

花韻仙語

发布时间:2025-09-25 12:09:13

|

607人浏览过

|

来源于php中文网

原创

java中利用正则表达式和stream api从混合字符串中高效提取数字

本文探讨了如何使用Java中的正则表达式和Stream API,从包含数字、字母和特殊字符的混合文本中提取数字。核心挑战在于,由非空白字符连接的数字应被视为一个整体,而由空白字符分隔的数字则应分别提取。文章详细介绍了两种基于Java 8/9+ Stream API的解决方案:一种利用Matcher.results()进行模式匹配,另一种则通过Pattern.splitAsStream()按空白符分段处理,并提供了相应的代码示例和注意事项。

在处理混合字符串数据时,我们经常需要从中精确地提取出数值信息。本教程将针对一个具体场景,即从包含数字、字母、特殊字符的文本中,按照特定规则(非空白字符连接的数字视为一个整体,空白字符分隔的数字视为独立部分)提取所有数字,提供两种高效的Java实现方案。

1. 方案一:使用 Matcher.results() 进行模式匹配

此方案适用于Java 9及以上版本,它通过一个精心构造的正则表达式直接匹配符合条件的数字序列。

1.1 正则表达式解析

我们需要的正则表达式是 [^\\s]*\\d+[^\\s]*。让我们分解一下它的含义:

  • [^\\s]*:匹配零个或多个非空白字符。这允许数字前面可以有字母或特殊字符。
  • \\d+:匹配一个或多个数字。这是我们想要提取的核心部分。
  • [^\\s]*:再次匹配零个或多个非空白字符。这允许数字后面可以有字母或特殊字符。

这个正则表达式的整体作用是捕获一个包含至少一个数字,且可能被非空白字符包围的完整序列。由于它在遇到空白字符时会停止匹配,因此能够满足“空白字符分隔的数字视为独立部分”的要求。

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

1.2 实现步骤与代码示例

Matcher.results() 方法返回一个 Stream,其中每个 MatchResult 代表一次成功的匹配。我们可以利用Stream API的链式操作来完成后续的数据清洗和转换。

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 = Pattern.compile("[^\\s]*\\d+[^\\s]*");

    /**
     * 从字符串中提取符合特定规则的整数列表。
     * 非空白字符连接的数字被视为一个整体。
     *
     * @param str 待处理的输入字符串。
     * @return 提取到的整数列表。
     */
    public static List getIntsUsingMatcherResults(String str) {
        return TEXT_WITH_DIGITS_PATTERN.matcher(str).results() // 获取所有匹配结果的Stream
            .map(MatchResult::group)                           // 提取每个匹配到的完整字符串
            .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("  abc123def 456 ghi789  -> " + getIntsUsingMatcherResults("  abc123def 456 ghi789  "));
    }
}

1.3 注意事项

  • 此方法要求Java 9或更高版本,因为 Matcher.results() 方法是在Java 9中引入的。
  • replaceAll("\\D+", "") 是关键步骤,它确保从捕获到的字符串中只保留数字。\\D 匹配任何非数字字符。

2. 方案二:基于 Pattern.splitAsStream() 的分段处理

此方案适用于Java 8及以上版本,它通过将原始字符串按空白字符分割成多个片段,然后对每个片段进行处理。

2.1 分割逻辑解析

首先,我们使用正则表达式 \s+ 来分割字符串。\s+ 匹配一个或多个空白字符(包括空格、制表符、换行符等)。这样,原始字符串就会被拆分成由非空白字符组成的多个子字符串。

Batch GPT
Batch GPT

使用AI批量处理数据、自动执行任务

下载

2.2 实现步骤与代码示例

Pattern.splitAsStream() 方法返回一个 Stream,其中每个元素是原始字符串中由分隔符分隔的子字符串。

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

public class NumberExtractorSplit {

    // 用于分割字符串的空白字符模式
    public static final Pattern WHITE_SPACES_PATTERN = Pattern.compile("\\s+");

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

    public static void main(String[] args) {
        System.out.println("使用 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("  abc123def 456 ghi789  -> " + getIntsUsingSplitAsStream("  abc123def 456 ghi789  "));
        System.out.println("   -> " + getIntsUsingSplitAsStream("   ")); // 测试全空白字符串
        System.out.println("abc -> " + getIntsUsingSplitAsStream("abc")); // 测试无数字字符串
    }
}

2.3 注意事项

  • 此方法要求Java 8或更高版本。dropWhile() 方法是在Java 9中引入的,但如果不需要处理输入字符串开头为空白字符的情况,或者可以接受一个空字符串作为结果,则在Java 8中可以省略 dropWhile 步骤。对于Java 8,如果需要处理开头空白字符,可能需要先用 trim() 或其他方式处理。
  • filter(s -> !s.isEmpty()) 是一个重要的补充,它用于处理那些在 replaceAll("\\D+", "") 之后变为空字符串的片段(例如,原始片段是 "abc" )。
  • Pattern.splitAsStream() 相较于 String.split() 的优势在于它直接生成 Stream,避免了创建中间数组,在处理大量数据时可能更高效。

3. 示例与输出

为了更好地展示两种方法的实际效果,我们统一运行以下测试用例:

public class MainTest {
    public static void main(String[] args) {
        String test1 = "ds[44]%6c";
        String test2 = "2021 ds[44]%6c";
        String test3 = "  abc123def 456 ghi789  ";
        String test4 = "   "; // 全空白字符串
        String test5 = "abc"; // 无数字字符串

        System.out.println("--- 使用 Matcher.results() ---");
        System.out.println("'" + test1 + "' -> " + NumberExtractor.getIntsUsingMatcherResults(test1)); // Output: [446]
        System.out.println("'" + test2 + "' -> " + NumberExtractor.getIntsUsingMatcherResults(test2)); // Output: [2021, 446]
        System.out.println("'" + test3 + "' -> " + NumberExtractor.getIntsUsingMatcherResults(test3)); // Output: [123, 456, 789]
        System.out.println("'" + test4 + "' -> " + NumberExtractor.getIntsUsingMatcherResults(test4)); // Output: []
        System.out.println("'" + test5 + "' -> " + NumberExtractor.getIntsUsingMatcherResults(test5)); // Output: []

        System.out.println("\n--- 使用 Pattern.splitAsStream() ---");
        System.out.println("'" + test1 + "' -> " + NumberExtractorSplit.getIntsUsingSplitAsStream(test1)); // Output: [446]
        System.out.println("'" + test2 + "' -> " + NumberExtractorSplit.getIntsUsingSplitAsStream(test2)); // Output: [2021, 446]
        System.out.println("'" + test3 + "' -> " + NumberExtractorSplit.getIntsUsingSplitAsStream(test3)); // Output: [123, 456, 789]
        System.out.println("'" + test4 + "' -> " + NumberExtractorSplit.getIntsUsingSplitAsStream(test4)); // Output: []
        System.out.println("'" + test5 + "' -> " + NumberExtractorSplit.getIntsUsingSplitAsStream(test5)); // Output: []
    }
}

输出结果:

--- 使用 Matcher.results() ---
'ds[44]%6c' -> [446]
'2021 ds[44]%6c' -> [2021, 446]
'  abc123def 456 ghi789  ' -> [123, 456, 789]
'   ' -> []
'abc' -> []

--- 使用 Pattern.splitAsStream() ---
'ds[44]%6c' -> [446]
'2021 ds[44]%6c' -> [2021, 446]
'  abc123def 456 ghi789  ' -> [123, 456, 789]
'   ' -> []
'abc' -> []

4. 总结与选择建议

两种方法都有效地解决了从混合字符串中提取数字的问题,并遵循了特定的分隔规则。

  • Matcher.results() (Java 9+)

    • 优点:正则表达式直接定义了要“捕获”的数字序列模式,逻辑上更直观地表达了“查找符合特定结构的数字组”。
    • 缺点:需要Java 9及以上版本。
    • 适用场景:当提取逻辑主要集中在识别特定模式的数字序列时,此方法更为直接。
  • Pattern.splitAsStream() (Java 8+)

    • 优点:利用空白字符进行分割,将问题分解为更小的、独立的片段处理,对于按分隔符处理的场景非常自然。在Java 8中可用(尽管dropWhile是Java 9特性,但可通过其他方式规避)。
    • 缺点:需要额外处理分割后可能产生的空字符串。
    • 适用场景:当核心问题是根据特定分隔符(如空白符)将字符串分解为多个逻辑单元时,此方法非常高效和简洁。

在实际开发中,您可以根据项目所使用的Java版本、个人偏好以及对代码可读性的考量来选择最合适的方案。两者都展示了Java Stream API在处理集合数据和进行转换方面的强大能力,使得代码更加简洁和富有表达力。

相关专题

更多
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中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

16861

2023.08.03

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

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

7

2025.12.31

热门下载

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

精品课程

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

共23课时 | 2.1万人学习

C# 教程
C# 教程

共94课时 | 5.7万人学习

Java 教程
Java 教程

共578课时 | 39.9万人学习

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

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