简体   繁体   English

如何将文件内容解析为变量?

[英]How can I parse the content of file to variables?

I have text file which looks like this : 我有一个看起来像这样的文本文件:

ABC=-1 Temp=2 Try=34 Message="some text" SYS=3 ABC = -1 Temp = 2 Try = 34 Message =“ some text” SYS = 3
ABC=-1 Temp=5 Try=40 Message="some more and different text" SYS=6 ABC = -1温度= 5尝试= 40消息=“更多和不同的文本” SYS = 6

and the pattern continues but only the numeric values and text inside the " " is changed. 并且模式继续,但仅更改了“”内的数字值和文本。

NOTE : the Message= could have multiple quotes as well. 注意Message =也可以有多个引号

I want to store the value of ABC,Temp,Try and SYS to int variables And Message to a String variable . 我想将ABC,Temp,Try和SYS的值存储到int变量中,并将消息存储String变量中

I am currently using: 我目前正在使用:

Scanner scanner = new Scanner(file);
while (scanner.hasNextLine()) {
  String line = scanner.nextLine();
  int count = line.indexOf("ABC=");
  if (count >= 0) {
    int clear = line.charAt(count + 3);
  }
}
scanner.close();

I thought of using the Scanner class and read line by line, but I am confused about how can I classify the line in different variables? 我曾考虑过使用Scanner类并逐行读取,但对于如何将行分类为不同的变量感到困惑。

First make a class that represents the data: 首先创建一个代表数据的类:

public static class MyData { // please pick a better name
    final int abc;
    final int temp;
    final int tryNumber; // try is a keyword
    final String message;
    final int sys;

    public MyData(int abc, int temp, int tryNumber, String message, int sys) {
      this.abc = abc;
      this.temp = temp;
      this.tryNumber = tryNumber;
      this.message = message;
      this.sys = sys;
    }
}

Then make a method that transforms a String into this class using Regex capture groups : 然后创建一个使用Regex捕获组String转换为此类的方法:

private static Pattern p =
  Pattern.compile("ABC=([^ ]+) Temp=([^ ]+) Try=([^ ]+) Message=\"(.+)\" SYS=([^ ]+)");

private static MyData makeData(String input) {
  int abc = 0, temp = 0, tryNumber = 0, sys = 0;
  String message = "";

  Matcher m = p.matcher(input);
  if (!(m.find()) return null;
  abc = Integer.parseInt(m.group(1));
  temp = Integer.parseInt(m.group(2));
  tryNumber = Integer.parseInt(m.group(3));
  message = m.group(4);
  sys = Integer.parseInt(m.group(5));

  return new MyData(abc, temp, tryNumber, message, sys);
}

Then read the file using a scanner: 然后使用扫描仪读取文件:

public static void main (String... args) throws Exception {
    File file = new File("/path/to/your/file.txt");
    List<MyData> dataList = new ArrayList<>();

    Scanner scanner = new Scanner(file);
    while (scanner.hasNextLine()) {
        String line = scanner.nextLine();
        MyData data = makeData(line);
        if(data != null) dataList.add(data);
    }
    scanner.close();
}

Here's a completely working demo on ideone 这是关于ideone的完整工作演示

You can use regex for this kind of parsing with a pattern of: 您可以将regex用于以下类型的解析:

"ABC=([+-]?\\d+) Temp=([+-]?\\d+) Try=([+-]?\\d+) Message=\"(.+)\" SYS=([+-]?\\d+)"

Pattern Breakdown ( Pattern Reference ): 模式分解( 模式参考 ):

  • ABC= - literal string ABC= -文字字符串
  • ([+-]?\\\\d+) - captures a positive or negative number in capture group 1 ([+-]?\\\\d+) -在捕获组1中捕获正数或负数
  • Temp= - literal string Temp= -文字字符串
  • ([+-]?\\\\d+) - captures a positive or negative number in capture group 2 ([+-]?\\\\d+) -在捕获组2中捕获正数或负数
  • Try= - literal string Try= -文字字符串
  • ([+-]?\\\\d+) - captures a positive or negative number in capture group 3 ([+-]?\\\\d+) -在捕获组3中捕获正数或负数
  • Message= - literal string Message= -文字字符串
  • \\"(.+)\\" captures a string in between double quotes in capture group 4 \\"(.+)\\"在捕获组4中捕获双引号之间的字符串
  • SYS= - literal string SYS= -文字字符串
  • ([+-]?\\\\d+) - captures a positive or negative number in capture group 5 ([+-]?\\\\d+) -在捕获组5中捕获正数或负数

If the String matches the pattern you can extract your values like this: 如果String与模式匹配,则可以像这样提取值:

public static void main(String[] args) throws Exception {
    List<String> data = new ArrayList() {{
        add("ABC=-1 Temp=2 Try=34 Message=\"some text\" SYS=3");
        add("ABC=-1 Temp=5 Try=40 Message=\"some more \"and\" different text\" SYS=6");
    }};
    String pattern = "ABC=([+-]?\\d+) Temp=([+-]?\\d+) Try=([+-]?\\d+) Message=\"(.+)\" SYS=([+-]?\\d+)";

    int abc = 0;
    int temp = 0;
    int tryNum = 0;
    String message = "";
    int sys = 0;
    for (String d : data) {
        Matcher matcher = Pattern.compile(pattern).matcher(d);
        if (matcher.matches()) {
            abc = Integer.parseInt(matcher.group(1));
            temp = Integer.parseInt(matcher.group(2));
            tryNum = Integer.parseInt(matcher.group(3));
            message = matcher.group(4);
            sys = Integer.parseInt(matcher.group(5));

            System.out.printf("%d %d %d %s %d%n", abc, temp, tryNum, message, sys);
        }
    }
}

Results: 结果:

-1 2 34 some text 3
-1 5 40 some more "and" different text 6

If you are already using the indexOf approach, the following code will work 如果您已经在使用indexOf方法,则以下代码将起作用

    String a = "ABC=-1 Temp=2 Try=34 Message=\"some text\" SYS=3";
    int abc_index = a.indexOf("ABC");
    int temp_index = a.indexOf("Temp");
    int try_index = a.indexOf("Try");
    int message_index = a.indexOf("Message");
    int sys_index = a.indexOf("SYS");
    int length = a.length();

    int abc = Integer.parseInt(a.substring(abc_index + 4, temp_index - 1));
    int temp = Integer.parseInt(a.substring(temp_index + 5, try_index - 1));
    int try_ = Integer.parseInt(a.substring(try_index + 4, message_index - 1));
    String message = a.substring(message_index + 9, sys_index - 2);
    int sys = Integer.parseInt(a.substring(sys_index + 4, length));

    System.out.println("abc : " + abc);
    System.out.println("temp : " + temp);
    System.out.println("try : " + try_);
    System.out.println("message : " + message);
    System.out.println("sys : " + sys);

This will give you the following 这将为您提供以下内容

abc : -1
temp : 2
try : 34
message : some text
sys : 3

This will work only if the string data you get has this exact syntax, ie, it contains ABC , Temp , Try , Message , and SYS . 仅当您获得的字符串数据具有完全相同的语法(即,它包含ABCTempTryMessageSYS Hope this helps. 希望这可以帮助。

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

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