【问题标题】:how to parse text files, where order matters如何解析文本文件,顺序很重要
【发布时间】:2011-05-11 16:28:33
【问题描述】:

我无法确定解析给定文本文件的方法。

这是文件中的一个条目:

type = "book"
callnumber = "1"
authors = "a"
title = "t"
publisher = "p"
year = "2023"

每个条目由一行空格(换行符)分隔。

所以我有这些变量(类型、电话号码、作者、标题....),并且需要阅读此文本并确定将它们设置为什么值。例如,当我读取“callnumber = 1”行时,我需要将该变量设置为 1。

这是我目前所拥有的。我一次读一行,例如type = "book",然后我将该行拆分为一个字符串数组,分隔符为",因此该数组将包含type =book。 现在我的问题是从那里走得更远。我想我可以逐个字符地循环遍历数组中的每个字符串,直到遇到空格。所以我会有type,但是我还没有任何数据要存储在类型中,并且抓取会给我book(忽略= 和空格),但是我如何将书归因于类型?

总之,我正在寻找一种方法来逐行解析文本文件,并根据我找到的单词分配变量值。

谢谢。

【问题讨论】:

  • 澄清一下,正如 Aaron 让我想到的那样,在我开始解决问题的方式上,我不一定需要帮助。我选择的方式似乎不必要地复杂,我希望有人指出更好的方式或算法。

标签: java string file text


【解决方案1】:

忽略当前路由,为什么不使用Properties.load(InputStream inputStream)

Properties properties = new Properties();
properties.load(new FileInputStream("filename"));

string type = properties.getProperty("type");
System.out.println(type);

【讨论】:

  • 嗯,这对我来说似乎有点难以理解,你能指出任何使用它的例子吗?
  • @Blackbinary 添加了快速而肮脏的示例
  • 完美,谢谢。它现在吐出"book",这很好,只需要去掉引号。一个问题,我假设如果我有一个包含多个条目的文本文件(例如多个 type 字段),如果我使用多个调用,它会按顺序遍历它们吗?
  • @Blackbinary 你不能有重复的键。你越走这条路,这就越适合 XML
【解决方案2】:

如果您的要求允许,我同意您应该采用 Properties 路线。下一个最佳选择是通过正则表达式单独处理每一行。

 String type = "default";
 int callnumber = 0;


 String line = "type = \"book\"";
    // String line = "callnumber = \"1\"";
 Pattern linePattern = Pattern.compile("(\\w*) = \"(.*)\"");

 Matcher matcher = linePattern.matcher(line);
 if ( !matcher.matches() ) {
     System.err.println("Bad line");
 }

 String name = matcher.group(1);
 String value = matcher.group(2);

 if ( "type".equals(name) ) {
     type = value;
 } else if ( "callnumber".equals(name) ) {
     callnumber = Integer.parseInt(value);
 } //...

在您的情况下,您可能希望将其集成到从文件中读取的 while 循环中,并将 line 替换为您刚刚从文件中读取的行。

【讨论】:

    【解决方案3】:

    添加到 Aaron 的解决方案中:

    Properties.load(new FileInputStream("<fileName>"));
    

    将加载属性并获取任何特定属性,

    使用 例如,

    Properties.getProperty("type") 
    

    会给你字符串“book”。

    【讨论】:

    • 你能发布一个简单的例子吗?我试过这个:import java.util.*; import java.io.*; public class reader { public static void main(String [] args) { Properties.load(new FileInputStream ("data.txt")); String data = Properties.getProperty("type"); System.out.println(data); } } 但我得到了关于静态上下文不能引用非静态方法的错误
    【解决方案4】:

    文本文件中变量的顺序是否总是相同的?

    我猜你不会问是不是这样。

    为什么不直接做一个方法:

    void assignVariableByName(String name, <type> value) {
        if(name.contains("type"))
            type = value;
        else if(name.contains("callnumber"))
            callnumber = value; 
    }
    

    然后使用->

    你有你拆分的字符串数组......然后你调用

    assignVariableByName(parsedLine[0],parsedLine[1]);
    

    【讨论】:

      【解决方案5】:

      为变量赋值可能已经在其他地方更干净地完成了。但是,如果您想“标记”您的字符串,请使用字符串标记器。

      新学派是使用String类的split方法。

      token[] = line.split("\s++")
      

      http://download.oracle.com/javase/6/docs/api/java/lang/String.html#split(java.lang.String)

      下面是老派的方式:

      http://download.oracle.com/javase/1.4.2/docs/api/java/util/StringTokenizer.html

      While(String line = someInput.readLine())
      
      StringTokenizer st = new StringTokenizer(line)
      while(st.hasMoreTokens)
      {
        String token = st.nextToken()
        //branch on token command, skip token '=', and assign on values
      }
      

      【讨论】:

      • 有趣的是,我的 Java 版本说 StringTokenizer 是一个遗留类,不鼓励在新代码中使用它:-P。
      • 确实如此。好久没有java了。貌似可以用 String.split() 代替。
      猜你喜欢
      • 1970-01-01
      • 2018-09-22
      • 2021-04-17
      • 2012-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多