【问题标题】:Parsing a text file in Java在 Java 中解析文本文件
【发布时间】:2010-09-13 02:09:43
【问题描述】:

输入文件示例:

ARTIST="unknown"
TITLE="Rockabye Baby"
LYRICS="Rockabye baby in the treetops
When the wind blows your cradle will rock
When the bow breaks your cradle will fall
Down will come baby cradle and all
"

必须将艺术家、标题和歌词字段提取到各自的字符串中,并且大写和格式保持不变。艺术家字段的此代码

while (readIn.hasNext()) {
    readToken= readIn.next();
    if (readToken.contains("ARTIST")) {
        artist= readIn.next();
        }
        if (readToken.contains("TITLE")){
            title= readIn.next();
    System.out.print(artist+" "+title);
}

最终打印出来:

"unknown"
TITLE null"unknown"
TITLE null"unknown"
TITLE

从代码中,我看不出为什么输出会这样打印。每次循环时,readToken 字符串都会被刷新,然后应该通过 contains() 方法进行比较。显然我在这里遗漏了一些东西。

那么,我是接近正确的轨道还是我在一个完全不同的城市?

【问题讨论】:

  • 令牌的分隔符是什么?
  • 您的代码无法编译。您是否在代码中粘贴?还是您只是尝试在 SO 上键入一些代码?
  • readIn 是什么类型的对象?此外,您在 readToken.contains)"TITLE") 中有一个不正确的 close paren 而不是 open paren。
  • 该代码看起来无法编译。
  • 该代码是来自 try-catch 块内部的 sn-p。 readIn 是一个扫描器对象。我想使用双引号作为分隔符,但不知道如何使用它们。所以我使用了等号。

标签: java file-io text-parsing


【解决方案1】:

从你的代码

while (readIn.hasNext()) {
    readToken= readIn.next();
    if (readToken.contains("ARTIST")) {
        artist= readIn.next();
        }
    if (readToken.contains("TITLE")){
        title= readIn.next();
    System.out.print(artist+" "+title);
}

如果假设被正确声明和实例化(变量artist、readToken和title),程序首先是 检查while条件中是否存在现有的下一行,如果是这样,则将字符串(我假设)readToken保存为下一行。如果 readToken 包含“ARTIST”,则将下一行保存为艺术家字符串。同样包含“TITLE”。当 while 循环重复时,您可能已经点击了 LYRICS,完全跳过了 TITLE,导致它为 NULL。

你想要的也许是节省

艺术家 = readToken; 或标题 = readToken;而是。

另外,如果您不想打印“ARTIST="ARTISTNAMEHERER" TITLE="TITLENAMEHERE"” 而是“ARTISTNAME, TITLENAME”,请不要忘记为艺术家和标题添加子字符串

【讨论】:

    【解决方案2】:

    除了 Alex Hart 的回答之外,我认为您可能会考虑使用 Java 的 Pattern 和 Matcher 类并使用组来获取匹配的参数,例如(未经测试):

    private static final Pattern RECORDING_HEADER = 
      new Pattern("(ARTIST=\\"(.*)\\")?(TITLE=\\"(.*)\\")?(LYRICS=\\"(.*)\\")?");
    

    那么当你在读一行的时候:

    String line = readIn.readLine(); // Presuming that readIn is a BufferedReader
    Matcher m = RECORDING_HEADER.matcher(line);
    
    if (m.matches()) {
      final int artistGroup = 2;
      String artist = m.group(artistGroup);
    
      final int titleGroup = 4;
      String title = m.group(titleGroup);
    
      final int lyricsGroup = 6;
      String lyrics = m.group(lyricsGroup);
    
      if (artist != null) {
        // You've got an artist...
      } else if (title != null) {
        // etc...
      }
    }
    

    【讨论】:

    • 即使我没有使用您的建议,我仍然选择您的回复作为答案,因为它确实让我走上了正确的道路。谢谢!
    • 谢谢。解析的另一种解决方案当然是使用ANTLR。有一个学习曲线,但值得根据您的解析要求。它的词法分析器也可以很好地为您服务。
    【解决方案3】:

    看起来你在这里做的是逐行阅读,但是当你找到你要找的东西时,你正在将你的变量设置到下一行。这可能会导致问题和超出范围的问题,并且很可能是您的不幸的征兆

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-25
      • 1970-01-01
      • 1970-01-01
      • 2011-09-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多