Java:如何确定正则表达式模式匹配失败的原因?

Java:如何确定正则表达式模式匹配失败的原因?,java,regex,Java,Regex,我使用正则表达式来匹配模式是否匹配,但我也想知道它何时失败 例如,假设我有一个“N{1,3}Y”的模式。我将它与字符串“NNNNY”匹配。我想知道它失败了,因为有太多的Ns。或者,如果我将它与字符串“XNNY”匹配,我想知道它失败了,因为字符串中有无效字符“X” 通过查看Java正则表达式包API(Java.util.regex),似乎只有在匹配成功时才能从Matcher类获得其他信息 有没有办法解决这个问题?或者正则表达式在这个场景中是一个选项吗?您需要的是解析器确定与您的表达式实际匹配的附近

我使用正则表达式来匹配模式是否匹配,但我也想知道它何时失败

例如,假设我有一个“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中不需要太多的掩蔽
  • 为您的表达式编写一个小型测试框架,在这里您可以轻松地将表达式放入,测试字符串,或者生成自动测试数据,并获得视觉反馈
我不知道有哪个正则表达式引擎在匹配过程中提供这些信息。这是不可能的。由于许多不同的原因,字符串可能无法匹配。而且,无论如何,没有引擎能做到这一点。这是一个开放式的问题,为什么有些东西不匹配。您可以定义与“不匹配”的特定情况相匹配的正则表达式,但不可能给出通用的答案。为什么“abcdef”不匹配?它的长度错误,没有任何“N”字符,不以Y结尾,是小写,等等。正则表达式的设计目的是快速有效地查找模式。您的需求与查找匹配项无关,而与分析输入有关。你可以用一个xustom模式或一组正则表达式来解决这个问题,对于每一个单独的错误,谢谢,我想我需要一个解析器。我想这证实了这一点。-1我认为这不是一个答案,而是一个好的评论。正则表达式很好,您只需要了解matcher类可以提供什么。
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