如何使用JavaAPI确定正则表达式匹配失败的位置

如何使用JavaAPI确定正则表达式匹配失败的位置,java,regex,Java,Regex,我进行了一些测试,用正则表达式验证输出。当它失败时,它报告输出X与正则表达式Y不匹配 我想在字符串中添加一些匹配失败的指示。例如,在回溯之前,匹配者在字符串中得到的最远距离是多少Matcher.hitEnd()就是我要找的一个例子,但我想要更一般的 这可能吗?如果您想在代码之外执行此操作,我会在将正则表达式插入代码之前测试它们。您可以使用一对replaceAll()调用来指示输入字符串的正匹配和负匹配。比方说,您想要验证一个十六进制字符串;以下内容将指示输入字符串的有效字符和无效字符 Strin

我进行了一些测试,用正则表达式验证输出。当它失败时,它报告输出X与正则表达式Y不匹配

我想在字符串中添加一些匹配失败的指示。例如,在回溯之前,匹配者在字符串中得到的最远距离是多少
Matcher.hitEnd()
就是我要找的一个例子,但我想要更一般的


这可能吗?

如果您想在代码之外执行此操作,我会在将正则表达式插入代码之前测试它们。

您可以使用一对
replaceAll()
调用来指示输入字符串的正匹配和负匹配。比方说,您想要验证一个十六进制字符串;以下内容将指示输入字符串的有效字符和无效字符

String regex = "[0-9A-F]"
String input = "J900ZZAAFZ99X"
Pattern p = Pattern.compile(regex)
Matcher m = p.matcher(input)
String mask = m.replaceAll('+').replaceAll('[^+]', '-')
System.out.println(input)
System.out.println(mask)
这将打印以下内容,在有效字符下为
+
,在无效字符下为
-

J900ZZAAFZ99X
-+++--+++-++-

您可以获取该字符串并对其进行迭代,每次迭代时从其末尾再删除一个字符,然后检查
hitEnd()


如果匹配失败,则
match.hitEnd()
会告诉您是否可以匹配更长的字符串。此外,您可以在输入序列中指定一个区域,该区域将被搜索以查找匹配项。因此,如果您有一个无法匹配的字符串,您可以测试其前缀以查看匹配失败的位置:

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

public class LastMatch {
    private static int indexOfLastMatch(Pattern pattern, String input) {
        Matcher matcher = pattern.matcher(input);
        for (int i = input.length(); i > 0; --i) {
            Matcher region = matcher.region(0, i);
            if (region.matches() || region.hitEnd()) {
                return i;
            }
        }

        return 0;
    }

    public static void main(String[] args) {
        Pattern pattern = Pattern.compile("[A-Z]+[0-9]+[a-z]+");
        String[] samples = {
                "*ABC",
                "A1b*",
                "AB12uv",
                "AB12uv*",
                "ABCDabc",
                "ABC123X"
        };

        for (String sample : samples) {
            int lastMatch = indexOfLastMatch(pattern, sample);
            System.out.println(sample + ": last match at " + lastMatch);
        }
    }
}
此类的输出为:

*ABC: last match at 0
A1b*: last match at 3
AB12uv: last match at 6
AB12uv*: last match at 6
ABCDabc: last match at 4
ABC123X: last match at 6

除非我遗漏了什么,否则它会告诉我文本是否与正则表达式不匹配,但不会告诉我哪里不匹配。这就是我要找的。这可能是你最好的选择:@Gonzo牧师:谢谢,Perl的“use re‘debug’”接近我要找的。类似的东西可以从Java调用,这很好,尽管我发现第二种情况令人困惑。整个字符串都匹配,为什么报告4?我建议:
region.matches();如果(region.hitEnd())…
。然后它会返回6,很好。我只测试了部分匹配,没有考虑完整字符串或其任何前缀的完全匹配。现在这是固定的。intput.length()
*ABC: last match at 0
A1b*: last match at 3
AB12uv: last match at 6
AB12uv*: last match at 6
ABCDabc: last match at 4
ABC123X: last match at 6