首页 > 解决方案 > 正则表达式模式以排除 whitspacs\es

问题描述

我有以下格式的行

9/14/2021 6:01:14 PM   42 (3224)   Receive rate: 39338 B/s
9/14/2021 6:01:29 PM   92 (940)   Receive rate: 215363 B/s

我需要从这里提取 2 条数据:时间戳和实际费率,例如

9/14/2021 6:01:14 PM, 39338
9/14/2021 6:01:29 PM, 215363

我正在使用分组并提出以下模式:

^(.*)\s*[0-9]*\s+\([0-9]+\)\s+Receive\s+rate:\s+([0-9]+)

有了这样的模式,我成功地返回了我的第二组(39338、215363),但是对于第一组,它超出了 AM/PM 点太远,第一组变成了9/14/2021 6:01:14 PM 42.

如果我将模式更改为

^(.*)   [0-9]*\s+\([0-9]+\)\s+Receive\s+rate:\s+([0-9]+) -> 3 spaces instead of the first \s* 

它符合预期,但不能保证会有 3 个空格,所以我需要使用 whitespace char零或更多

标签: javaregexdatetimejava-timedatetime-parsing

解决方案


分别检索 Date-Time 和 Receive-Rate 部分。

我建议您分别检索 Date-Time 和 Receive-Rate 部分。要检索 Date-Time 部分,您可以使用丰富的java.timeAPI,然后可以使用 Java RegEx API 来检索 Receive-Rate 部分。

检索日期时间部分

您可以使用DateTimeFormatter#parse(CharSequence, ParsePosition)将字符串解析为可以从中检索到的TemporalAccessor字符串LocalDateTime

Trail: Date Time了解有关现代日期时间 API *的更多信息。

检索 Receive-Rate 部分

您可以使用正则表达式, (?<=(?:Receive rate: ))\d+(?=(?: B\/s))where(?<=(?:Receive rate: ))(?=(?: B\/s))has 分别用作正向后视模式和正向前瞻模式。

完整演示:

import java.text.ParsePosition;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        // Test
        Stream.of(
                "9/14/2021 6:01:14 PM   42 (3224)   Receive rate: 39338 B/s",
                "9/14/2021 6:01:29 PM   92 (940)   Receive rate: 215363 B/s"
        )
        .forEach(s -> System.out.printf(
                            "Timestamp: %s, Receive rate: %s%n", 
                            getTimestampPart(s),
                            getReceiveRate(s)
        ));
    }

    static String getTimestampPart(String str) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("M/d/uuuu h:mm:ss a", Locale.ENGLISH);
        return LocalDateTime.from(dtf.parse(str, new ParsePosition(0))).format(dtf);
    }

    static String getReceiveRate(String str) {
        Matcher matcher = Pattern.compile("(?<=(?:Receive rate: ))\\d+(?=(?: B\\/s))").matcher(str);
        return matcher.find() ? matcher.group() : "";
    }
}

输出:

Timestamp: 9/14/2021 6:01:14 PM, Receive rate: 39338
Timestamp: 9/14/2021 6:01:29 PM, Receive rate: 215363

ONLINE DEMO


* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,则可以使用ThreeTen-Backport,它将大部分java.time功能向后移植到 Java 6 和 7。如果您正在为 Android 项目和 Android API 工作level 仍然不符合 Java-8,请检查Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project


推荐阅读