我的文字格式如下:
<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是好东西:)感谢所有帮助:)
答案 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/上使用您的示例进行了测试,似乎有效......
编辑:当然,令牌的规则尚未应用 - 认为你自己可以做到这一点......