繁体   English   中英

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

[英]How do I parse a text file to write certain lines in another text file using java?

我正在学习如何使用 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();
    }
}

这是单元测试以确保代码有效

package com.grenader.example;

import com.grenader.example.PairParser;
import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

public class PairParserTest {

    @Test
    public void getValue_Ok() {
        PairParser parser = new PairParser("born time 9 AM London -- kingNumber 1234567890 -- address: abc/cd/ef -- birthmonth: unknown");

        assertEquals("1234567890", parser.getValue("kingNumber"));
        assertEquals("unknown", parser.getValue("birthmonth"));
    }

    @Test(expected = IllegalArgumentException.class)
    public void getValue_Null() {
        new PairParser(null);
        fail("This test should fail with Exception");
    }

    @Test(expected = IllegalArgumentException.class)
    public void getValue_EmptyLine() {
        new PairParser("");
        fail("This test should fail with Exception");
    }

    @Test()
    public void getValue_BadData() {
        PairParser parser = new PairParser("bad data bad data");
        assertEquals(0, parser.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]*)$

少写,多做。

暂无
暂无

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

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