2009-08-24 133 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樹,以獲得你所需要的:)