首页 > 解决方案 > 未知字符上的java正则表达式匹配器异常

问题描述

所以我有一个字符串,我想将其拆分为不同类型的标记,作为更大解析器的一部分。

String input = "45 + 31.05 * 110 @ 54";

我使用 javas 正则表达式库 Pattern 和 Matcher 来解释我的正则表达式并找到匹配项。

String floatRegex = "[0-9]+(\\.([0-9])+)?";
String additionRegex = "[+]";
String multiplicationRegex = "[*]";
String integerRegex = "[0-9]+"

我所有的正则表达式都被合并到一个主正则表达式中,不同的正则表达式之间带有管道符号。

String masterOfRegexes = "[0-9]+(\\.([0-9])+)?|[+]|[*]|[0-9]+"

我将此模式发送到 Pattern.compile() 并获取匹配器。当我从左到右运行 matcher.find() 时,我希望得到这个结构,直到应该抛出 InvalidInputException 的“@”符号。

[
  ["Integer": "45"],
  ["addition": "+"],
  ["Float": "31.05"],
  ["multiplication": "*"],
  ["Integer": "110"]
  Exception should be thrown...
]

问题是 matcher.find() 完全跳过了“@”符号,而是找到了“@”之后的下一个整数的匹配,即“54”。

为什么它会跳过“@”符号,我怎样才能让它在我的模式中无法识别的字符上引发异常?

标签: javaregextokenize

解决方案


正则表达式匹配或不匹配。在您的示例数据中,它不会跳过 @,它只是不匹配它。

您可以做的是识别单个捕获组中的有效匹配项,并在循环匹配项时检查组 1 是否不为空。

如果不是,则该模式具有有效的第 1 组匹配,否则您可以抛出异常。

请参阅正则表达式演示Java 演示

String regex = "([0-9]+(?:\\.[0-9]+)?|[+]|[*]|[0-9]+)|\\S+";
String string = "45 + 31.05 * 110 @ 54";

Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(string);

while (matcher.find()) {
    if (matcher.group(1) == null) {
        // your Exception here
        // throw new Exception("No match!");
        System.out.println(matcher.group() + " -> no match");
    } else {
        System.out.println(matcher.group(1) + " -> match");
    }
}

输出

45 -> match
+ -> match
31.05 -> match
* -> match
110 -> match
@ -> no match
54 -> match

推荐阅读