2011-03-03 43 views
7

我有一个文本文件,我需要使用正则表达式进行分析。我需要捕获文本是在多组这样的:如何在java中使用正则表达式捕获多行模式?

truck 
zDoug 
Doug's house 
(123) 456-7890 
[email protected] 
30 
61234.56 
8/10/2003 

vehicle 
eRob 
Rob's house 
(987) 654-3210 
[email protected] 

在这个例子中我需要捕获的卡车,然后在接下来的七年lines.In换句话说,在这个“块”我有8组。这是我做过尝试,但它不会捕捉下一行:

(truck)\n(\w). 

注:我使用的程序RegExr测试之前,我移植到Java的我正则表达式。

+2

如果需要逐行读取输入线,它有什么用正则表达式来呢? – 2011-03-03 03:34:30

+0

@nikita因为我想形成团体,其中包括新线 – lampShade 2011-03-03 03:41:11

回答

5
(?m)^truck(?:(?:\r\n|[\r\n]).+$)* 

这是假设整个文本已经被读入一个字符串(例如,你不是逐行读取文件),但它不是不是假定行分隔符始终为\n,如代码所示。至少应该允许\r\n\r,这也是(?:\r\n|[\r\n])所做的。但它仍然只匹配一个分隔符,所以匹配在块结束处的双线分隔符之前停止。

一旦你匹配的数据块,你可以上线分隔拆分它来获得各条线。这里有一个例子:

Pattern p0 = Pattern.compile("(?m)^truck(?:(?:\r\n|[\r\n]).+$)*"); 
Matcher m = p0.matcher(data); 
while (m.find()) 
{ 
    String fullMatch = m.group(); 
    int n = 0; 
    for (String s : fullMatch.split("\r\n|[\r\n]")) 
    { 
    System.out.printf("line %d: %s%n", n++, s); 
    } 
} 

输出:

line 0: truck 
line 1: zDoug 
line 2: Doug's house 
line 3: (123) 456-7890 
line 4: [email protected] 
line 5: 30 
line 6: 61234.56 
line 7: 8/10/2003

我也假设每行数据包含至少一个字符,并且该数据块之间的空白行真的是空的 - 也就是说,没有空格,TAB或其他不可见字符。

(BTW:为了测试RegExr该正则表达式,除去(?m)并检查multiline箱代替RegExr通过的ActionScript供电,所以规则是有点不同的对于的Java -Powered正则表达式测试仪,检查。 RegexPlanet

+0

很好的回答谢谢艾伦! – lampShade 2011-03-03 21:40:46

+0

多好的回答。对此,我真的非常感激。正则表达式非常强大 – lampShade 2011-03-03 22:30:05

3

我认为,为了跨越多行的模式应该在DOTALL模式下进行编译,像

Pattern p = Pattern.compile("truck\\n(.*\\n){7}", Pattern.DOTALL); 
+0

这正则表达式会更接近正确的*无*号的'DOTALL'标志。事实上,'。*'最初会消耗整个文档的其余部分。然后它可能会稍微回退一些,但它仍然会匹配最后一次换行。 – 2011-03-03 07:33:35

+0

啊,贪心! :-)错过了一个“?”在最后...非常感谢您指出它! – mazaneicha 2011-03-03 12:53:38

+0

没有必要让量词不贪心。只要摆脱'DOTALL'标志,点将不再符合换行符。 – 2011-03-03 16:12:24

3

这种模式应该工作((.*|\n)*)

+0

这个工程!谢谢! – 2016-10-31 03:32:16