我正在try 构建一个复杂的Java 17正则表达式,但在某些方面失败了.

我希望匹配的正则表达式/子字符串称为"metric set".一个指标集由6个segments组成,这6个部分中的每一个都可以是不同的"token type"中的任何一个.

第一个令牌类型为"distance token",由1个或多个数字[0-9]后跟双引号组成.距离标记的示例为:12"6"73"等.

第二种令牌类型是"numeric token"并且简单地由数字字符[0-9]组成.重要的是要注意,数字令牌也可以是有符号的(这意味着,有些可以是负数),并且在它们之前包含减号("-").数字令牌的例子有:918293-4-15等.

第三种令牌类型是"random token".此令牌可以以1+个可选数字字符[0-9]开头,也可以省略.则令牌将有一个大写的"D",后跟一个3或6.随机令牌的例子有:D3D612D34D6等.

第四个令牌类型可以是"不适用"令牌,在这种情况下,值必须正好是N/A.

第五种令牌类型称为"greater-than token",由1+数字[0-9]后跟加号("+")组成.大于标记的示例有:3+12+1+0+19+等.

第六种令牌类型称为"ignorables token",由单词MeleeRanged组成.

这些是标记类型,同样,正则表达式的6个不同段允许不同的段是不同的标记类型,如下所述.

第一段可以是以下任何令牌类型:距离令牌、随机令牌、可忽略令牌或不适用的令牌.

第二段可以是除距离令牌或可忽略令牌之外的任何令牌类型.

第三段可以是以下令牌类型中的任何一种:大于令牌、随机令牌或不适用令牌.

第4段可以是除距离令牌或可忽略令牌之外的任何令牌类型.

第五段可以是除距离令牌或可忽略令牌之外的任何令牌类型.

第6段可以是除距离令牌或可忽略令牌之外的任何令牌类型.

请向我展示Java 17代码,该代码实例化满足这些条件的字符串正则表达式,然后将输入字符串与该正则表达式进行匹配,并在匹配时从输入字符串中提取匹配的度量集(所有6个段).

以下是符合所有这些规则的匹配字符串的几个示例:

Flamer [IGNORES COVER, TORRENT] 12" D6 N/A 4 0 1
Grav-gun [ANTI-VEHICLE 2+] 18" 2 3+ 5 -1 2
Grav-pistol [ANTI-VEHICLE 2+, PISTOL] 18" 1 3+ 4 -1 2
Hand flamer [IGNORES COVER, PISTOL, TORRENT] 12" D6 N/A 3 0 1

以下是我的最新代码,代表了我到目前为止所做的最好try :

import java.util.regex.*;

public class MetricSetRegexMatcher {
    public static void main(String[] args) {
        String regex = "(\\d+\"|D[36]|Melee|Ranged|N/A)(?!.*\\d+\")(\\d+|D[36]|Melee|Ranged|N/A)(\\d+\\+|D[36]|N/A)(\\d+|D[36]|Melee|Ranged|N/A)(\\d+|D[36]|Melee|Ranged|N/A)(\\d+|D[36]|Melee|Ranged|N/A)";

        String input = "Hello there: 18\" 2 3+ 9 -4 D6";

        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(input);
        if (matcher.matches()) {
            for (int i = 1; i <= matcher.groupCount(); i++) {
                System.out.println("Segment " + i + ": " + matcher.group(i));
            }
        } else {
            System.out.println("No match!");
        }
    }
}

当运行此命令时,我得到输出"No Match!"我想知道我的正则表达式在哪里不符合我的标准.理想情况下,我能够匹配并从字符串中提取18" 2 3+ 9 -4 D6,用于后续处理.

推荐答案

这一点:

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

public class MetricSetRegexMatcher {
    public static void main(String[] args) {
        String regex = ""
                + "(\\d+\"|D[36]|Melee|Ranged|N/A) "
                + "(\\d+|D[36]|Melee|Ranged|N/A) "
                + "(\\d+\\+|D[36]|N/A) "
                + "(\\d+|D[36]|Melee|Ranged|N/A) "
                + "(-?\\d+|D[36]|Melee|Ranged|N/A) " 
                + "(\\d+|D[36]|Melee|Ranged|N/A)";
        Pattern pattern = Pattern.compile(regex);

        List<String> inputs = List.of(
                "Hello there: 18\" 2 3+ 9 -4 D6",
                "Flamer [IGNORES COVER, TORRENT] 12\" D6 N/A 4 0 1",
                "Grav-gun [ANTI-VEHICLE 2+] 18\" 2 3+ 5 -1 2",
                "Grav-pistol [ANTI-VEHICLE 2+, PISTOL] 18\" 1 3+ 4 -1 2",
                "Hand flamer [IGNORES COVER, PISTOL, TORRENT] 12\" D6 N/A 3 0 1");

        for (String input : inputs) {
            System.out.println("input " + input);

            Matcher matcher = pattern.matcher(input);
            if (matcher.find()) {
                for (int i = 1; i <= matcher.groupCount(); i++) {
                    System.out.println("Segment " + i + ": " + matcher.group(i));
                }
            } else {
                System.out.println("No match!");
            }
        }
    }
}

打印:

input Hello there: 18" 2 3+ 9 -4 D6
Segment 1: 18"
Segment 2: 2
Segment 3: 3+
Segment 4: 9
Segment 5: -4
Segment 6: D6
input Flamer [IGNORES COVER, TORRENT] 12" D6 N/A 4 0 1
Segment 1: 12"
Segment 2: D6
Segment 3: N/A
Segment 4: 4
Segment 5: 0
Segment 6: 1
input Grav-gun [ANTI-VEHICLE 2+] 18" 2 3+ 5 -1 2
Segment 1: 18"
Segment 2: 2
Segment 3: 3+
Segment 4: 5
Segment 5: -1
Segment 6: 2
input Grav-pistol [ANTI-VEHICLE 2+, PISTOL] 18" 1 3+ 4 -1 2
Segment 1: 18"
Segment 2: 1
Segment 3: 3+
Segment 4: 4
Segment 5: -1
Segment 6: 2
input Hand flamer [IGNORES COVER, PISTOL, TORRENT] 12" D6 N/A 3 0 1
Segment 1: 12"
Segment 2: D6
Segment 3: N/A
Segment 4: 3
Segment 5: 0
Segment 6: 1

Java相关问答推荐

日食IDE 2024-03在Ubuntu下崩溃,导致hr_err_pid.log

为什么我的画布没有显示在PFA应用程序中?

Java Streams在矩阵遍历中的性能影响

对运行在GraalVM-21上的JavaFX应用程序使用分代ZGC会警告不支持JVMCI,为什么?

条件加载@ManyToMany JPA

Exe4j创建的应用程序无法再固定在任务栏Windows 11上

Java 21虚拟线程执行器的性能比池化操作系统线程的执行器差?

在springboot 3中,当我调用api endpoint时,会出现404

如何集成语义发布和BitBucket(Java项目)

Kotlin Val是否提供了与Java最终版相同的可见性保证?

使用htmlunit和java单击按钮

垃圾收集时间长,会丢弃网络连接,但不会在Kubernetes中反弹Pod

当构造函数创建一个新实例时,Java为什么需要&new";

在Eclipse中可以使用外部字体吗?

在具有Quarkus Panache的PostgreSQL中将JSON数据存储为JSONB时,会将其存储为转义字符串

在Java中比较同一多维数组的两个不同的字符串元素

为什么我得到默认方法的值而不是被覆盖的方法的值?

在JSON上获取反斜杠

Java 8 中 ByteBuffer 和 BitSet 的奇怪行为

ChromeDriver 版本 117+ 强制另存为对话框 - 如何绕过? (selenium/Java)