2009-08-24 87 views
1

我传递一个字符串到我的歌曲解析器的方法,它失败了,我不明白为什么。每一件事情是返回null或0为什么我的匹配器失败?

我的解析器方法是

public static Song parseSong(String songString){ 
    Map<String, String> songMap = new HashMap<String, String>(); 
    Pattern pattern = Pattern.compile(".*<key>(.+)</key><(.+)>(.+)</.+>.*\n"); 
    Scanner scanner = new Scanner(songString); 
    if(scanner.hasNext(pattern)) 
    { 
    String line = scanner.next(pattern); 
    Matcher matcher = pattern.matcher(line); 
    MatchResult result = matcher.toMatchResult(); 
    songMap.put(result.group(1), result.group(3)); 
    } 
    int count = 0, rating = 0; 
    try{ 
    count = Integer.parseInt(songMap.get("Play Count")); 
    } 
    catch(Exception e) 
    { 
    //bury this for now will handle when rest is working 
    } 
    try{ 
    rating = Integer.parseInt(songMap.get("Rating")); 
    } 
    catch(Exception e) 
    { 
    //bury this for now will handle when rest is working 
    } 
    return new Song(songMap.get("Name"), songMap.get("Artist"), songMap.get("Album"), 
     songMap.get("Genre"), count, rating, songMap.get("Location")); 

}

 String songString = "<key>Track ID</key><integer>160</integer>\n"+ 
    "<key>Name</key><string>Ashley</string>\n"+ 
    " <key>Artist</key><string>Escape the Fate</string>\n"+ 
    " <key>Composer</key><string>Luca Gusella</string>\n"+ 
    " <key>Album</key><string>This War Is Ours</string>\n"+ 
    " <key>Genre</key><string>Metal</string>\n"+ 
    "<key>Kind</key><string>AAC audio file</string>\n"+ 
    " <key>Size</key><integer>7968219</integer>\n"+ 
    " <key>Total Time</key><integer>246503</integer>\n"+ 
    " <key>Track Number</key><integer>17</integer>\n"+ 
    " <key>Year</key><integer>2005</integer>\n"+ 
    " <key>Date Modified</key><date>2009-07-27T01:17:29Z</date>\n"+ 
    " <key>Date Added</key><date>2009-07-27T01:17:00Z</date>\n"+ 
    "<key>Play Count</key><integer>150</integer>\n"+ 
    " <key>Bit Rate</key><integer>256</integer>\n"+ 
    " <key>Sample Rate</key><integer>44100</integer>\n"+ 
    " <key>Comments</key><string>\"Amanda\" performed by Aisha Duo from the CD Quiet Songs, courtesy of Obliq Sound. Written by Luca Gusella, published by Editions ObliqMusic (GEMA). All Rights Reserved. Used by Permission. </string>\n"+ 
    " <key>Skip Count</key><integer>1</integer>\n"+ 
    " <key>Skip Date</key><date>2009-07-27T01:46:32Z</date>\n"+ 
    " <key>Artwork Count</key><integer>1</integer>\n"+ 
    " <key>Persistent ID</key><string>A4D6F35FE9F41B58</string>\n"+ 
    " <key>Track Type</key><string>File</string>\n"+ 
    " <key>Location</key><string>file://localhost/C:/Documents%20and%20Settings/MB24244/Desktop/music/07%20Knees.m4a</string>\n"+ 
    "<key>File Folder Count</key><integer>4</integer>\n"+ 
    "afgjdhfshsgsughghanoise\n"+ 
    "<key>Library Folder Count</key><integer>1</integer>\n"+ 
    "<key>Rating</key><integer>100</integer>"; 

谁能帮助解释一下什么是错我的做法,为什么组不工作(这似乎是问题)

回答

7

为什么不使用XML解析器解析XML

虽然看着是不是很好,因为它本质上是造型map,而不是造型<song>

看你的正则表达式为什么你要找结束\n行了XML的例子。看起来你依次匹配每一行,我不相信这些将包含新行字符。

但是,这种方法不使用扫描仪的作品。请注意,我已经改变了正则表达式来删除行尾。

Map<String, String> songMap = new HashMap<String, String>(); 

    Pattern pattern = Pattern 
      .compile(".*<key>(.+)</key><(.+)>(.+)</.+>.*"); 

    String[] lines = songString.split("\n"); 

    for (String line : lines) { 
     Matcher matcher = pattern.matcher(line); 
     if (matcher.matches()) { 
      songMap.put(matcher.group(1), matcher.group(3)); 
     } 
    } 

你也可以让它与扫描仪一起工作。

+0

嗯,我正在写这个应用程序,这是作为一个培训练习,我希望能够学习一点关于解析我的意思把它放到这一点很容易。我正在尝试为一个宠物项目解析一个itunes music library.xml。如果我无法弄清楚,我将转而使用已经写过的其他人。 – 2009-08-24 15:47:00

+0

我已经做了一些小的修改来获得代码的工作实现。 – pjp 2009-08-24 16:05:08

1

第二次投票使XML成为有效的XML(单个顶级节点),然后使用XML解析器。

但是我最终怀疑\ n,不知道有多少Java的正则表达式库喜欢这个?

0

不要试图编写解析器,除非您已经知道要解析的文件的规则。

你写的正则表达式不遵循很多XML文件的规则。

如果这是您第一次编写正则表达式,您应该尝试学习一些更容易解析的东西。也许甚至是你自己创建的简单文件格式。

1
if(scanner.hasNext(pattern)) 
{ 
    String line = scanner.next(pattern); 
    Matcher matcher = pattern.matcher(line); 
    matcher.toMatchResult(); 
    songMap.put(result.group(1), result.group(3)); 
} 

你pattern.matcher(线)创建的匹配是一个全新的对象,它不知道你刚发现有扫描仪的匹配任何东西。你想要的是这样的:

MatchResult result = scanner.match(); 

这个正则表达式也需要一些工作。如果每条记录都出现在自己的行上,则无需在任一端使用".*"进行填充,也无需匹配换行。另外,我建议你使用".+?"而不是".+"。为什么,read this

0

+1 to using。+?

除此之外,我会建议不要在这种情况下使用模式,因为你似乎有一个很容易解析的文件。我想: - 分割文件中的行由行 - 使用简单的字符串方法来获取内容(似乎只有3个在你的XML不同的标签)

如果文件格式会改变,变得更复杂的我会去与真正的XMLParser,只是遍历XML树,以获得你所需要的:)