需要正则表达式匹配第一个实例直到下一个实例(不包括下一个“向前看”)Java

需要正则表达式匹配第一个实例直到下一个实例(不包括下一个“向前看”)Java,java,regex,parsing,Java,Regex,Parsing,我不熟悉编程和正则表达式,所以这是我的免责声明 我正试图解析一个wireshark日志,我已经用tshark将它转换成一个txt文件 我的程序的要点是从txt文件的顶部开始,匹配数据包头之间的所有文本 所有数据包都以Frame\s+\d开头,不包括下一个数据包头,并将该文本放入字符串中 我正在实例化一个对象(Packets),然后将它们添加到ArrayList,以供以后处理 我需要收集从数据包头1到数据包1结尾/数据包头2开头的所有文本,不包括数据包头2 Frame 1 (186 bytes o

我不熟悉编程和正则表达式,所以这是我的免责声明

我正试图解析一个wireshark日志,我已经用tshark将它转换成一个txt文件

我的程序的要点是从txt文件的顶部开始,匹配数据包头之间的所有文本

所有数据包都以
Frame\s+\d
开头,不包括下一个数据包头,并将该文本放入字符串中

我正在实例化一个对象(
Packets
),然后将它们添加到
ArrayList
,以供以后处理

我需要收集从数据包头1到数据包1结尾/数据包头2开头的所有文本,不包括数据包头2

Frame 1 (186 bytes on wire, 186 bytes captured)
    Arrival Time: Sep 19, 2013 13:25:19.937150000
    [Time delta from previous captured frame: 0.000000000 seconds]
    [Time delta from previous displayed frame: 0.000000000 seconds]
    [Time since reference or first frame: 0.000000000 seconds]
    Frame Number: 1
    Frame Length: 186 bytes
    Capture Length: 186 bytes
    [Frame is marked: False]
    [Protocols in frame
............................A bunch of more packet data...............
    Encrypted Packet: 88FE0AFA38B3E1994B907F778FC42CD4FBD967F3D9101679...

Frame 2 (60 bytes on wire, 60 bytes captured)
    Arrival Time: Sep 19, 2013 13:25:19.938495000
    [Time delta from previous captured frame: 0.001345000 seconds]
    [Time delta from previous displayed frame: 0.001345000 seconds]
我试过:

(Frame\s\d)*.?Frame\s\d
但不是骰子

我一直在访问rubular.com,想看看我是否能在这方面取得成功,但我似乎无法满足我的需要


想法?

考虑
/your/path
中的文件
packets.txt
,其中包含您发布的示例

这里有一个解决方案

try {
    // trivial file operations
    String path = "/your/path/packets.txt";
    File file = new File(path);
    BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
    String line = null;
    StringBuilder contents = new StringBuilder();
    while ((line = br.readLine()) != null) {
        contents.append(line);
    }
    br.close();
    // the Pattern
    Pattern p = Pattern.compile("Frame\\s\\d\\s(.+?(?=Frame|$))", Pattern.MULTILINE);
    // If you actually need the "Frame etc." header matched as well, here's
    // an alternate Pattern:
    // Pattern p = Pattern.compile("(Frame\\s\\d\\s.+?(?=Frame|$))", Pattern.MULTILINE);
    // matching...
    Matcher m = p.matcher(contents);
    // iterating over matches and printing out group 1
    while (m.find()) {
        System.out.println("Found: " + m.group(1));
    }
}
// "handling" FileNotFoundException
catch (Throwable t) {
    t.printStackTrace();
}
输出:

Found: (186 bytes on wire, 186 bytes captured)    Arrival Time: Sep 19, 2013 13:25:19.937150000    [Time delta from previous captured frame: 0.000000000 seconds]    [Time delta from previous displayed frame: 0.000000000 seconds]    [Time since reference or first frame: 0.000000000 seconds]    
Found: (60 bytes on wire, 60 bytes captured)    Arrival Time: Sep 19, 2013 13:25:19.938495000    [Time delta from previous captured frame: 0.001345000 seconds]    [Time delta from previous displayed frame: 0.001345000 seconds]
模式的说明

  • 它查找或多或少以原始图案开头的文本(“帧、空格、数字、空格”)
  • 它存储下一个出现的内容,包括换行符,但在出现新的“框架”文本或输入文本结束时停止
  • 文本匹配点2存储在一个组中(组0是整个匹配,特定组从索引1开始)
编辑:性能和内存优化提示

  • 步骤很小但很明显:将
    模式声明为常量,这样它只编译一次

  • 不要填充一个随着每次匹配而增长的
    ArrayList
    ,而是将每个匹配写入某个文件夹中的单个文件-这将执行得很慢,但如果实现良好,应该允许在
    while(m.find())
    循环的每次迭代中对匹配的
    字符串进行垃圾收集

  • 迭代结束后,您必须再次迭代处理每个小文件

  • 如果这还不够,或者对数据的大小不起作用,那么您可能希望实现自己的自定义解析器,或者以某种方式预块数据,但考虑到您最初的问题是关于
    模式本身,而不是性能,这已经超出了范围


你的意思可能是
*?
,而不是
*?
。这里有两个小问题。。。首先,我需要每个数据包中的所有内容存储在单个数组元素中。所以只是标题不起作用,所以如果我的原始帖子中没有明确说明,我很抱歉。第二个问题以堆空间错误的形式出现。这个解决方案适用于小文件,但对于280MB的日志文件,它只是耗尽内存并停止。线程“main”java.lang.OutOfMemoryError中出现异常:java heap spaceI已经给出了一个旋转,使用FR和BR读取每一行,并使用类似“line+=line+”%“;”的内容在每一行后面添加一个小分隔符,对于小文件来说效果很好。当文件增大时,由于内存不足,我的解决方案不再适用。我认为这里要做的事情是读取所有行,直到Frame\\s\\d的下一个实例,并将该字符串处理到数组中,然后再次将该字符串重置为空,并再次解析,直到header的下一次迭代。这在我的头脑中是清楚的,只是在我的代码中没有。@jvazquez为堆获取一个
OutOfMemoryError
,这意味着您已经创建了一条通向许多未被垃圾收集的对象的路径。这可能是因为您正在将每个匹配项添加到
ArrayList
,而后者不断增长,而引用仍然指向内存中的
对象。我将很快编辑我的答案,其中有一些要点可能对您有所帮助。我感谢您的帮助。作为一个新手确实考验了你的毅力,因为我已经有好几次想冲破这堵墙了。LOL@jvazquez对于新手来说,你面临着一个相当不错的挑战,所以冲墙是可以理解的:D