简体   繁体   English

使用Java 8在文本文件中搜索字符串

[英]Search for a String in a Text File using Java 8

I have a long text file that I want to read and extract some data out of it. 我有一个很长的文本文件,我想阅读并从中提取一些数据。 Using JavaFX and FXML, I am using FileChooser to load the file to get the file path. 使用JavaFX和FXML,我使用FileChooser加载文件以获取文件路径。 My controller.java has the following: 我的controller.java有以下内容:

private void handleButtonAction(ActionEvent event) throws IOException {
        FileChooser fileChooser = new FileChooser();
        FileChooser.ExtensionFilter extFilter = new FileChooser.ExtensionFilter("TXT files (*.txt)", "*.txt");
        fileChooser.getExtensionFilters().add(extFilter);
        File file = fileChooser.showOpenDialog(stage);
        System.out.println(file);
         stage = (Stage) button.getScene().getWindow();


    }

Sample of text file: Note some of the file content is split between 2 lines. 文本文件示例:请注意,某些文件内容分为2行。 for Example -Ba\\ 10.10.10.3 is part of the first line. 例如-Ba \\ 10.10.10.3是第一行的一部分。

net ip-interface create 10.10.10.2 255.255.255.128 MGT-1 -Ba \
10.10.10.3
net ip-interface create 192.168.1.1 255.255.255.0 G-1 -Ba \
192.168.1.2 
net route table create 10.10.10.5 255.255.255.255 10.10.10.1 -i \
MGT-1
net route table create 10.10.10.6  255.255.255.255 10.10.10.1 -i \
MGT-1

I am looking for a way to search this (file) and output the following: 我正在寻找一种方法来搜索此(文件)并输出以下内容:

MGT-1 ip-interface 10.10.10.2 
MGT-1 Backup ip-interface 10.10.10.3
G-1 ip-interface 192.168.1.1
G-1 Backup Ip-interface 192.168.1.2
MGT-1 route 10.10.10.5 DFG 10.10.10.1
MGT-1 route 10.10.10.6 DFG 10.10.10.1

Of course you can read the input file as the stream of lines using BufferedReader.lines or Files.lines . 当然,您可以使用BufferedReader.linesFiles.lines将输入文件作为行流Files.lines However the tricky thing here is how to deal with the trailing "\\" . 然而,这里棘手的是如何处理尾随的"\\" There are several possible solutions. 有几种可能的解决方案。 You may write your own Reader which wraps an existing Reader and just ignores the slash followed by EOL. 您可以编写自己的Reader来包装现有的Reader然后忽略EOL后面的斜杠。 Alternatively you can write a custom Iterator or Spliterator which takes the BufferedReader.lines stream as the input and handles this case. 或者,您可以编写自定义IteratorSpliterator ,它将BufferedReader.lines流作为输入并处理此案例。 I'd suggest to use my StreamEx library which already has a method for such tasks called collapse : 我建议使用我的StreamEx库,它已经有一个方法用于collapse这样的任务:

StreamEx.ofLines(reader).collapse((a, b) -> a.endsWith("\\"), 
                                  (a, b) -> a.substring(0, a.length()-1).concat(b));

The first argument is the predicate which is applied for two adjacent lines and should return true if lines should be merged. 第一个参数是应用于两个相邻行的谓词,如果应合并行,则应返回true。 The second argument is the function which actually merges two lines (we chop the slash via substring , then concatenate the next line). 第二个参数是实际合并两行的函数(我们通过substring切断斜杠,然后连接下一行)。

Now you can just split the line by the whitespace and convert it to one or two output lines according to your task. 现在,您可以按空格分割线条,并根据您的任务将其转换为一条或两条输出线条。 Better to do it by the separate method. 最好通过单独的方法来做到这一点。 The whole code: 整个代码:

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.regex.Pattern;
import java.util.stream.Stream;

import javax.util.streamex.StreamEx;

public class ParseFile {
    static Stream<String> convertLine(String[] fields) {
        switch(fields[1]) {
        case "ip-interface":
            return Stream.of(fields[5]+" "+fields[1]+" "+fields[3],
                             fields[5]+" Backup "+fields[1]+" "+fields[7]);
        case "route":
            return Stream.of(fields[8]+" route "+fields[4]+" DFG "+fields[6]);
        default:
            throw new IllegalArgumentException("Unrecognized input: "+
                                               String.join(" ", fields));
        }
    }

    static Stream<String> convert(Reader reader) {
        return StreamEx.ofLines(reader)
                .collapse((a, b) -> a.endsWith("\\"), 
                          (a, b) -> a.substring(0, a.length()-1).concat(b))
                .map(Pattern.compile("\\s+")::split)
                .flatMap(ParseFile::convertLine);
    }

    public static void main(String[] args) throws IOException {
        try(Reader r = new InputStreamReader(
            ParseFile.class.getResourceAsStream("test.txt"))) {
            convert(r).forEach(System.out::println);
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM