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