0

嗨,

我在逐行读取文件时遇到逻辑问题。我知道你可以用 来做到这一点BufferedReader,但有时我有写在更多行中的“值”,这很重要。

我正在阅读的文件示例:

   <#FIELD NAME = DESC> Some text that goes

        over multiple lines

        which is needed</#FIELD>

    <#FIELD NAME = TEMP> some values are just a single line</#FIELD>

我需要解析字段名称,如上面的 TEMP 或 DESC,然后提取这些括号之间的值<#FIELD NAME =DESC>important values </#FIELD>。但是我不确定如何“识别”一个条目具有多行值或单值行,然后在使用 BufferedReader 时将其保存到变量中。

我真的很感激任何提示或例子来引导我走向正确的方向!

因为逐行阅读它并没有帮助我取得进步......我不会发布整个代码,因为我认为有一种更简单的阅读方式,你会了解我到目前为止所做的事情小片段。

if (line.contains("<#FIELD NAME = AUTOR>"))
{
    String autor = line.substring(line.indexOf(">") + 1, line.indexOf("</#"));
    metaData.setAutor(autor.trim());
}
else if (line.contains("<#FIELD NAME = DOKUMENTNR>"))
{
    String dokumentnr = line.substring(line.indexOf(">") + 1, line.indexOf("</#"));
    metaData.setDoukumentnr(dokumentnr.trim());
    ...
4

5 回答 5

1
while((line=reader.readLine()) != null){
    if(isDescOrTemp(line)){
        if(line.endsWith("</#FIELD>"){
           //one line field
        } else
        while(!line.endsWith("</#FIELD>"){
            //read more lines
            line=reader.readLine();
            //store line somewhere
        }
    }
}
于 2012-11-21T10:12:45.960 回答
1

据我了解,如果您没有分层数据(如树),则意味着您有一个列表,因此您正在寻找一种拆分它的方法。通常你应该编写一个干净的解析器,但如果不是这样,你可以尝试破解你的方式。

String s = "<#FIELD NAME = DESC> Some text that goes\nover multiple lines\nwhich is needed</#FIELD>\n<#FIELD NAME = TEMP> some values are just a single line</#FIELD>";
String[] fs = s.split("<#FIELD NAME = ");
for (String f : fs) {
    System.out.println(f);
}

生产

DESC> Some text that goes
over multiple lines
which is needed</#FIELD>

TEMP> some values are just a single line</#FIELD>

</#FIELD>在此之后,您需要通过删除末尾的并读取开头的键来清理结果字符串。

于 2012-11-21T10:19:47.263 回答
1

尝试类似的东西

public string ReadField(BufferedReader reader) 
{
    string line = reader.readLine();
    while (line.indexOf("</#FIELD>") == -1)
    {
        line += reader.readLine(); // This does not preserve line breaks
    }

    return line;
}

在原始代码中,类似

string line = ReadField(myReader); // This reads up to the next field

if(line.contains("<#FIELD NAME = AUTOR>")){
   String autor = line.substring(line.indexOf(">")+1,line.indexOf("</#"));
   metaData.setAutor(autor.trim());
} else if(line.contains("<#FIELD NAME = DOKUMENTNR>")) {
   String dokumentnr = line.substring(line.indexOf(">")+1,line.indexOf("</#"));
   metaData.setDoukumentnr(dokumentnr.trim());
}
于 2012-11-21T10:21:20.677 回答
0

您可以遵循如下伪代码:

While(!EOF)
{
    string line = readLine();
    while( !EOF && ! line.contains("</#FIELD>"))
    {
        line += readLine();
    }
    // Here you get a line with matching `begin` and `end`

    // ... do operations as needed

    // reset line
    line = "";
}
于 2012-11-21T10:18:45.033 回答
0

我的版本:

    Pattern p = Pattern.compile("<#FIELD.+</#FIELD>", Pattern.DOTALL);
    Scanner s = new Scanner(new File("test.txt"));
    for(;;) {
        String field = s.findWithinHorizon(p, 0);
        if (field == null) {
            break;
        }
        // here you got a full #FIELD element, parse it
        System.out.println(field);
    }
于 2012-11-21T10:26:13.433 回答