Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/398.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用java解析文本文件以在另一个文本文件中写入某些行?_Java_Java.util.scanner - Fatal编程技术网

如何使用java解析文本文件以在另一个文本文件中写入某些行?

如何使用java解析文本文件以在另一个文本文件中写入某些行?,java,java.util.scanner,Java,Java.util.scanner,我正在学习如何用Java处理文件。我有一个示例文件,其中包含密钥对和它的值。我试图找到一个密钥对,若它匹配,那个么输出文件将同时更新密钥对和它的值。我能够在输出文件中获取密钥对,但也无法获取值。Stringbuilder可以在这里添加字符串,但我不知道如何添加 下面是我的输入和输出文件 Input File: born time 9 AM London -- kingNumber 1234567890 -- address: abc/cd/ef -- birthmonth: unknown b

我正在学习如何用Java处理文件。我有一个示例文件,其中包含密钥对和它的值。我试图找到一个密钥对,若它匹配,那个么输出文件将同时更新密钥对和它的值。我能够在输出文件中获取密钥对,但也无法获取值。Stringbuilder可以在这里添加字符串,但我不知道如何添加

下面是我的输入和输出文件

Input File:

born time 9 AM London -- kingNumber 1234567890 -- address: abc/cd/ef -- birthmonth: unknown
born time 9 AM Europe -- kingNumber 1234567890 -- address: abc/cd/ef -- birthmonth: december

Expected Output File:

kingNumber 1234567890 birthmonth unknown 
kingNumber 1234567890 birthmonth unkbown

Current Output File:

kingNumber birthmonth 
kingNumber birthmonth
我能够将密钥对(在本例中为“kingNumber”和“birthmonth”)写入输出文件,但我不确定我能做些什么来获得它的值

    String kn = "kingNumber:";
    String bd = "birthmonth:";

    try {

        File f = new File("sample.txt");
        Scanner sc = new Scanner(f);
        FileWriter fw = new FileWriter("output.txt");


        while(sc.hasNextLine()) {
            String lineContains = sc.next();
            if(lineContains.contains(kn)) {
                fw.write(kn  + "\n");
                // This is where I am stuck. What
                // can I do to get it's value (number in this case).
            }
            else if(lineContains.contains(bd)) {
                fw.write(bd);
                // This is where I am stuck. What
                // can I do to get it's value (birthday in this case).
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

我已经编写了一个简单的解析器,它遵循您示例中的数据格式。 您需要这样称呼它:

PairParser parser = new PairParser(lineContains);
然后可以通过成对键从解析器中获取值 如何获得价值:

parser.getValue("kingNumber")
请注意,键没有尾随列字符

解析器代码如下所示:

package com.grenader.example;

import java.util.HashMap;
import java.util.Map;

public class PairParser {

    private Map<String, String> data = new HashMap<>();

    /**
     * Constructor, prepare the data
     * @param dataString line from the given data file
     */
    public PairParser(String dataString) {
        if (dataString == null || dataString.isEmpty())
            throw new IllegalArgumentException("Data line cannot be empty");

        // Spit the input line into array of string blocks based on '--' as a separator
        String[] blocks = dataString.split("--");

        for (String block : blocks)
        {
            if (block.startsWith("born time")) // skip this one because it doesn't looks like a key/value pair
                continue;
            String[] strings = block.split("\\s");
            if (strings.length != 3) // has not exactly 3 items (first items is empty), skipping this one as well
                continue;
            String key = strings[1];
            String value = strings[2];
            if (key.endsWith(":"))
                key = key.substring(0, key.length()-1).trim();

            data.put(key.trim(), value.trim());
        }
    }

    /**
     * Return value based on key
     * @param key
     * @return
     */
    public String getValue(String key)
    {
        return data.get(key);
    }

    /**
     * Return number of key/value pairs
     * @return
     */
    public int size()
    {
        return data.size();
    }
}

您可以将
java.util.regex.Pattern
&
java.util.regex.Matcher
与类似的模式一起使用:

^born\stime\s([a-zA-Z0-9\s]*)\s--\skingNumber\s(\d+)\s--\saddress:\s([a-zA-Z0-9\s/]*)\s--\sbirthmonth:\s([a-zA-Z0-9\s]*)$

写得少,做得多。

不太确定问题出在哪里,但您可能希望使用.nextLine()而不是.next()。@JacobB。我更新了我的问题,也许现在会更清楚。我正在尝试获取那些缺少的值。您应该查看字符串格式(regex)和分隔符,以从字符串中提取数据。您在这方面到底做了什么?您能解释一下吗?这应该提供一个如何和为什么的想法:例如,上面的模式需要70个步骤来匹配所有4个捕获组(步骤越少,速度越快;通常可以优化它们);也可以看到我上面链接的答案。我知道你想做什么,但我对构造函数的输入有点困惑。这里输入的是整个文本文件,而不是一个单词,所以我不确定如何更改它。构造函数需要一行文本。代码中的这一行:String lineContains=sc.next();在lineContains变量中包含所需的行。您可以在这一行之后创建解析器。这很奇怪。我正试着按照你说的去做,但不知什么原因它不起作用。什么不起作用?:)可能尝试System.out.println()一些值或调试应用程序。
^born\stime\s([a-zA-Z0-9\s]*)\s--\skingNumber\s(\d+)\s--\saddress:\s([a-zA-Z0-9\s/]*)\s--\sbirthmonth:\s([a-zA-Z0-9\s]*)$