正则表达式满足3个独立的案例

Regex which satisfies 3 separate cases

我试图找出一个正则表达式,它可以与Java的String,String(ReGEX)一起使用,以便从文件中得到一行"行"。

回车不定义行的结尾,而逗号定义行的结尾,但不是所有逗号。如果逗号位于括号、单引号或注释(/*comment,more comment*/)之间,则不表示行尾。

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
1 test fixed(5,2),
  2 another_test char(12),
  2 a_third_test,
    3 one pic'9{9}V.99',
    3 two pic'9,999V.99',
    3 three fixed(7,2),
  /* test,t*/
  /*test 2,*/
  /*and more */
  2 another_field fixed bin(13),
  2 a_really_long_super_long_field_name_requiring_two_lines_for_declaration
    char(1),
  2 a_field char(8);

预期输出为(为了清晰起见,省略了 和额外的空格):

1
2
3
4
5
6
7
8
9
10
1 test fixed(5,2)
2 another_test char(12)
2 a_third_test
3 one pic'9{9}V.99'
3 two pic'9,999V.99'
3 three fixed(7,2)
/* test,t*//*test 2,*//*and more */  2 another_field fixed bin(13)
2 a_really_long_super_long_field_name_requiring_two_lines_for_declaration
    char(1)
2 a_field char(8)

我想出了三个独立的regex表达式来获得这三个部分:

  • ,(?![^(]*\))—所有不在括号内的逗号
  • (,(?![^']*'))—所有不单引号的逗号
  • (,(?![^\/\*]*\*\/))—所有不在评论中的逗号

我试过和一个或多个1〔3〕加入他们,但得到以下信息:

1
2
3
4
5
6
7
8
9
1 test fixed
2 another_test char
2 a_third_test
3 one pic
3 two pic
3 three fixed
2 another_field fixed bin
2 a_really_long_super_long_field_name_requiring_a_line_break_...        char
2 a_field char

这3个regex表达式有没有一种方法(或者有更好的表达式?)可以组合起来找到满足所有3个的组吗?

更新:

我可以用一些简单的Java来完成具体的事情,但是我愿意用正则表达式作为一种学术习惯。

1
2
3
4
5
6
7
8
9
10
String temp ="";
for(String line:text.split("
")){
  if(line.trim().charAt(line.trim().length()-1) == ',' || line.trim().charAt(line.trim().length()-1) == ';'){
    System.out.println(temp + line);
    temp ="";
  } else {
    temp += line.trim();
  }
}


我想你可能有点想过头了。要记住,正则表达式是用来解析正则语言的。当您需要检查是否在注释或parens或其他内容中以了解逗号的含义时,您所看到的是上下文相关的语言(见下图)。

By J. Finkelstein (Own work)



<div class=

1
2
3
4
5
6
7
8
9
, via Wikimedia Commons">。</P><blockquote>
  <p>
By J. Finkelstein (Own work) [CC BY-SA 3.0 (https://creativecommons.org/licenses/by-sa/3.0)
</p>
</blockquote>号<P>也就是说,在行尾匹配逗号和分号就足够简单了。<wyn>/\s*(.*?)[,;]$/gsm</wyn>适用于问题中的测试输入。但是,这并没有考虑到</P>[cc]test fixed(5,2),
/* a,
   multi-line,
   comment,
*/

在我看来,最好的解决方法是在开始使用\/\*.*?\*\/进行解析之前丢弃注释。如果您需要保留注释,您可能会使用否定的查找方法,但这些方法效率很低,最好是编写一个标记器/解析器。