我有一些测试,其中使用正则表达式验证输出。当测试失败时,会报告输出X未匹配正则表达式Y。
我想要添加一些指示,用于指出匹配失败的字符串位置。例如,在回溯之前匹配器在字符串中最远到达的位置。Matcher.hitEnd()
是我所寻找的情况之一,但我需要更通用的方法。
这个是否可能做到?
我有一些测试,其中使用正则表达式验证输出。当测试失败时,会报告输出X未匹配正则表达式Y。
我想要添加一些指示,用于指出匹配失败的字符串位置。例如,在回溯之前匹配器在字符串中最远到达的位置。Matcher.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
region.matches(); if (region.hitEnd()) ...
。然后对于该情况返回 6。 - TimKhitEnd()
。int farthestPoint(Pattern pattern, String input) {
for (int i = input.length() - 1; i > 0; i--) {
Matcher matcher = pattern.matcher(input.substring(0, i));
if (!matcher.matches() && matcher.hitEnd()) {
return i;
}
}
return 0;
}
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
-+++--+++-++-
如果你想在代码之外进行操作,我会使用 rubular 来测试正则表达式,然后再将其粘贴到代码中。