正则表达式 - 仅当前一部分匹配时匹配此部分

时间:2017-01-29 16:27:48

标签: java regex

我的文字格式如下:

<command>,<cabinet>,<drawer>,<report>

规则是:

<command>:仅限3位数字,
<cabinet>:1-4位数字,
<drawer>:A到I之间的1位字母数字,
<report>:1-4位数字

每个细分仅在前一个细分存在时才有意义。 可以假设机柜总是存在,否则,只是找到命令是没用的。

示例:

SRH,898
SRH,898,G
SRH,898,G,900

非示例:

SRH,,,898          // <report> without <cabinet> or <drawer>
SRH,898,,900       // <report> without <drawer>. Take only upto SRH,898  .. ignoring the rest

我想出了这个:[a-z$]{3},\d{1,4},([a-i])?(,\d+)?

问题:
SRH,898,,900之类的案例对此正则表达式有效,而理想情况下它应该无效,因为<report>(900)不存在{{ 1}}。我希望它仅在<{strong> <drawer>存在的情况下尝试匹配<report> ,在这种情况下,<drawer>将由<drawer>分隔来自,,如果<report>也存在。

我想我可以在两个循环中执行此操作,第二个会过滤掉连续的<report> - s,但希望可以做得更好。

任何帮助?

由于

最终更新https://regex101.com/r/i7HnLf/3是好东西:)感谢所有帮助:)

3 个答案:

答案 0 :(得分:0)

即使你设法提出了你想要的正则表达式,即保持以前匹配的段的状态,也几乎不可能维持。

由于您要打开并解析每个文件,因此最好明确地在代码中处理您的要求。

答案 1 :(得分:0)

以下代码完成工作:

public class FourpartsRegEx {

   static Pattern pattern = Pattern.compile(
      "([A-za-z]{3})" + // <command> : 3 digit letters only,
      "(,"            +
      "(\\d{1,4})"    + // <cabinet> : 1-4 digit numeric,
      "(,"            +
      "([A-I])"       + // <drawer>  : 1 digit alphanumeric between A to I,
      "(,"            +
      "(\\d{1,4})"    + // <report>  : 1-4 digit numeric
      ")?)?)?" +
      ""
      );

   static void test( String expr ) {
      final Matcher m = pattern.matcher( expr );
      if( m.matches()) {
         System.err.printf( "%s match ==> %s, %s, %s, %s\n",
            expr, m.group( 1 ), m.group( 3 ), m.group( 5 ), m.group( 7 ));
      }
      else {
         System.err.printf( "%s doesn't match\n", expr );
      }
   }

   public static void main( String[] args ) {
      // Matches
      test( "SRH,898" );
      test( "SRH,898,G" );
      test( "SRH,898,G,900" );

      // Non Matches
      test( "SRH,,,898"    ); // <report> without <cabinet> or <drawer>
      test( "SRH,898,,900" ); // <report> without <drawer>
   }
}

执行:

SRH,898 match ==> SRH, 898, null, null
SRH,898,G match ==> SRH, 898, G, null
SRH,898,G,900 match ==> SRH, 898, G, 900
SRH,,,898 doesn't match
SRH,898,,900 doesn't match

答案 2 :(得分:-1)

检查此正则表达式:

^([^,][^,]*)($|,([^,][^,]*))($|,([^,][^,]*))($|,([^,][^,]*))

从一开始,搜索至少有1个非令牌, 后跟一行结尾,或者一个,后跟另一个至少为1的字符串,依此类推......

http://regex101.com/上使用您的示例进行了测试,似乎有效......

编辑:当然,令牌的规则尚未应用 - 认为你自己可以做到这一点......