Java:如何确定正则表达式模式匹配失败的原因?
我使用正则表达式来匹配模式是否匹配,但我也想知道它何时失败 例如,假设我有一个“N{1,3}Y”的模式。我将它与字符串“NNNNY”匹配。我想知道它失败了,因为有太多的Ns。或者,如果我将它与字符串“XNNY”匹配,我想知道它失败了,因为字符串中有无效字符“X” 通过查看Java正则表达式包API(Java.util.regex),似乎只有在匹配成功时才能从Matcher类获得其他信息Java:如何确定正则表达式模式匹配失败的原因?,java,regex,Java,Regex,我使用正则表达式来匹配模式是否匹配,但我也想知道它何时失败 例如,假设我有一个“N{1,3}Y”的模式。我将它与字符串“NNNNY”匹配。我想知道它失败了,因为有太多的Ns。或者,如果我将它与字符串“XNNY”匹配,我想知道它失败了,因为字符串中有无效字符“X” 通过查看Java正则表达式包API(Java.util.regex),似乎只有在匹配成功时才能从Matcher类获得其他信息 有没有办法解决这个问题?或者正则表达式在这个场景中是一个选项吗?您需要的是解析器确定与您的表达式实际匹配的附近
有没有办法解决这个问题?或者正则表达式在这个场景中是一个选项吗?您需要的是解析器确定与您的表达式实际匹配的附近字符串。这是一个非常重要的问题,可能会以指数时间运行(例如,搜索所有长度相似的字符串以找到匹配项)
所以,简而言之,不是。我想你应该使用解析器,而不是简单的正则表达式
正则表达式很好地为字符串提供匹配项,但在提供非匹配项时就不是这样了,更不用说解释匹配失败的原因了。它可能会起作用,但我不知道您是否需要它 使用
matches
时,如果整个序列不匹配,则会失败,但您仍然可以使用find
查看序列的其余部分是否包含该模式,从而了解失败的原因:
import java.util.regex.*;
import static java.lang.System.out;
class F {
public static void main( String ... args ) {
String input = args[0];
String re = "N{1,3}Y";
Pattern p = Pattern.compile(re);
Matcher m = p.matcher(input);
out.printf("Evaluating: %s on %s%nMatched: %s%n", re, input, m.matches() );
for( int i = 0 ; i < input.length() ; i++ ) {
out.println();
boolean found = m.find(i);
if( !found ) {
continue;
}
int s = m.start();
int e = m.end();
i = s;
out.printf("m.start[%s]%n"
+"m.end[%s]%n"
+"%s[%s]%s%n",s,e,
input.substring(0,s),
input.substring(s,e),
input.substring(e) );
}
}
}
在第一个输出中:N[NNY]
您可以知道哪里有过多的N,在第二个输出中:X[NNY]
有一个X
这是其他输出
C:\Users\oreyes\java\re>java F NYXNNXNNNNYX
Evaluating: N{1,3}Y on NYXNNXNNNNYX
Matched: false
m.start[0]
m.end[2]
[NY]XNNXNNNNYX
m.start[7]
m.end[11]
NYXNNXN[NNNY]X
m.start[8]
m.end[11]
NYXNNXNN[NNY]X
m.start[9]
m.end[11]
NYXNNXNNN[NY]X
图案在那里,但整个表情不匹配
从文档中理解find、matches和lookingAt是如何工作的有点困难(至少在我身上发生过这种情况),但我希望这个示例可以帮助您解决这个问题
匹配就像是/^YOURPATTERNHERE$/
“看”就像是/^YOURPATTERNHERE/
查找类似于/YOURPATTERNHERE/
我希望这能有所帮助。对于像“N{1,3}Y”这样的简单表达式,您将自己在没有工具的情况下找到解决方案。但对于更复杂的表达,我的经验表明:
- 将较大的表达式拆分为较小的表达式,并独立测试它们李>
- 由于您希望获得快速反馈,因此可以使用交互式shell(如Beanshell)快速测试某些字符串和模式,而无需大编译、公共静态void main(bla…)等。或者尝试scala完成此任务。Sed是另一个使用正则表达式的强大工具,但是语法上存在细微的差异,这可能会引入新的错误李>
- 通常,掩蔽是一个问题。因为反斜杠需要另一个反斜杠,所以从JTextField读取表达式是一个优势,在JTextField中不需要太多的掩蔽李>
- 为您的表达式编写一个小型测试框架,在这里您可以轻松地将表达式放入,测试字符串,或者生成自动测试数据,并获得视觉反馈李>
C:\Users\oreyes\java\re>java F NYXNNXNNNNYX
Evaluating: N{1,3}Y on NYXNNXNNNNYX
Matched: false
m.start[0]
m.end[2]
[NY]XNNXNNNNYX
m.start[7]
m.end[11]
NYXNNXN[NNNY]X
m.start[8]
m.end[11]
NYXNNXNN[NNY]X
m.start[9]
m.end[11]
NYXNNXNNN[NY]X