java - 单个 Java 正则表达式中的多个匹配项

标签 java regex

是否可以在单个正则表达式中匹配以下内容以获取第一个单词,然后是数字列表?

this 10 12 3 44 5 66 7 8    # should return "this", "10", "12", ...
another 1 2 3               # should return "another", "1", "2", "3"

EDIT1: 我的实际数据并不是这么简单,数字实际上是更复杂的模式,但出于说明目的,我已将问题简化为简单的数字,因此我确实需要一个正则表达式答案.

每行的数字长度未知,但都匹配一个简单的模式。

以下仅匹配“this”和“10”:

([\p{Alpha}]+ )(\d+ ?)+?

删除最后的 ? 匹配“this”和“8”。

我原以为最后一组 (\d+ ?)+ 会多次进行数字匹配,但事实并非如此,如果可能的话,我找不到这样做的语法.

我可以多次通过,只分别搜索名称和后面的数字,但想知道是否可以在单个表达式中进行? (如果不是,有什么原因吗?)


EDIT2:正如我在一些评论中提到的,这是 Advent of Code(2020 年第 7 天)中的一个问题。我一直在寻找最干净的解决方案(谁不喜欢稍微打磨一下?)

这是我使用的最终解决方案 (kotlin),但在 1 个正则表达式中尝试这样做的时间太长,所以我发布了这个问题。

val bagExtractor = Regex("""^([\p{Alpha} ]+) bags contain""")
val rulesExtractor = Regex("""([\d]+) ([\p{Alpha} ]+) bag""")

// bagRule is a line from the input
val bag = bagExtractor.find(bagRule)?.destructured!!.let { (n) -> Bag(name = n) }
val contains = rulesExtractor.findAll(bagRule).map { it.destructured.let { (num, bagName) -> Contain(num = num.toInt(), bag = Bag(bagName)) } }.toList()
Rule(bag = bag, contains = contains)

尽管现在知道它可以在 1 行中完成,但我还没有实现它,因为我认为它在 2 行中更干净。

最佳答案

我认为你正在寻找的东西可以通过在 \s+ 上拆分字符串来实现,除非我遗漏了什么。

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        String str = "this 10 12 3 44 5 66 7 8";
        String[] parts = str.split("\\s+");
        System.out.println(Arrays.toString(parts));
    }
}

输出:

[this, 10, 12, 3, 44, 5, 66, 7, 8]

如果你只想从字符串中选择字母文本和整数文本,你可以这样做

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

public class Main {
    public static void main(String[] args) {
        String str = "this 10 12 3 44 5 66 7 8";
        Matcher matcher = Pattern.compile("(\\b\\p{Alpha}+\\b)|(\\b\\d+\\b)").matcher(str);
        while (matcher.find()) {
            System.out.println(matcher.group());
        }
    }
}

输出:

this
10
12
3
44
5
66
7
8

或作为

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

public class Main {
    public static void main(String[] args) {
        String str = "this 10 12 3 44 5 66 7 8";

        List<String> list = Pattern.compile("(\\b\\p{Alpha}+\\b)|(\\b\\d+\\b)")
                            .matcher(str)
                            .results()
                            .map(MatchResult::group)                                                        
                            .collect(Collectors.toList());

        System.out.println(list);
    }
}

输出:

[this, 10, 12, 3, 44, 5, 66, 7, 8]

关于java - 单个 Java 正则表达式中的多个匹配项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65186269/

相关文章:

java - 每次添加到文件时如何阻止文件被覆盖?

java - @Autowired 与 XML

javascript - 使用正则表达式解析 bool 算术,包括括号?

javascript - 从javascript中的关键字数组计算字符串中的出现次数

c# - 用于在替换包含数字的组中保留数字的正则表达式

java.net.ConnectException : Connection refused with Google Maps

java - 如何防止按钮环绕在 Java 中显示?

java - HTTP 状态 405 - 此 URL 不支持 HTTP 方法 POST

Javascript:正数和负数的正则表达式,但没有小数点

一个或多个由空格分隔的单词的正则表达式