我使用正则表达式来匹配模式是否匹配,但我也想知道它何时失败。
例如,假设我有一个“N {1,3} Y”的模式。我将它与字符串“NNNNY”匹配。我想知道它失败了因为Ns太多了。或者如果我将它与字符串“XNNY”匹配,我想知道它失败了,因为字符串中包含无效字符“X”。
通过查看Java正则表达式包API(java.util.regex),匹配成功时,似乎只能从Matcher类中获取其他信息。
有没有办法解决这个问题?或者在这种情况下,正则表达式是一个选项吗?
答案 0 :(得分:9)
我想你应该使用解析器,而不是简单的正则表达式。
正则表达式可以很好地为字符串提供匹配,但在提供非匹配时并不完全相同,更不用说解释匹配失败的原因了。
答案 1 :(得分:2)
它可能有效,但我不知道你是否需要它。
使用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) );
}
}
}
输出:
C:\Users\oreyes\java\re>java F NNNNY
Evaluating: N{1,3}Y on NNNNY
Matched: false
m.start[1]
m.end[5]
N[NNNY]
m.start[2]
m.end[5]
NN[NNY]
m.start[3]
m.end[5]
NNN[NY]
C:\Users\oreyes\java\re>java F XNNY
Evaluating: N{1,3}Y on XNNY
Matched: false
m.start[1]
m.end[4]
X[NNY]
m.start[2]
m.end[4]
XN[NY]
在第一个输出中:N[NNNY]
你可以告诉那里有太多的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
模式存在,但整个表达不匹配。
有点难以理解查找,匹配和查找是如何从文档中工作的(至少这发生在我身上)但我希望这个例子可以帮助你解决这个问题。
匹配就像/^YOURPATTERNHERE$/
lookingAt就像/^YOURPATTERNHERE/
find就像/YOURPATTERNHERE/
我希望这会有所帮助。
答案 2 :(得分:1)
您要求的是解析器确定附近的字符串,该字符串实际上与您的表达式匹配。这是一个非常重要的问题,可能会在指数时间内运行(例如,搜索所有可能的相似长度的字符串以找到匹配项。)
所以,简而言之,没有。
答案 3 :(得分:0)
对于像“N {1,3} Y”这样的简单表达式,您将自己找到没有工具的解决方案。但对于更复杂的表达方式,我的经验表明: