Java使用正則表達式解析LRC歌詞文件


LRC歌詞是一種應用廣泛的歌詞文件,各主流播放器都支持。

lrc歌詞文本中含有兩類標簽:

1、標識標簽(ID-tags)

[ar:藝人名]
[ti:曲名]
[al:專輯名]
[by:編者(指編輯LRC歌詞的人)]
[offset:時間補償值] 其單位是毫秒,正值表示整體提前,負值相反

2、 時間標簽(Time-tag)

標准格式: [分鍾:秒.毫秒] 歌詞

例:[01:15.62]

 

在這里為了簡便我只是解析了時間標簽,對其進行解析時使用到了正則表達式:

正則表達式語法參考:http://www.cnblogs.com/wuqianling/p/5686139.html

 

示例歌詞:

[ar:胡彥斌]
[ti:月光]
[00:00.86]月光(秦時明月主題曲)
[00:06.31]歌手 胡彥斌
[00:08.68]作詞 林文炫
[00:10.49]作曲 胡彥斌
[00:20.11]月光色
[00:22.30]女子香
[00:24.51]淚斷劍
[00:26.70]情多長
[00:28.95]有多痛
[00:30.97]無字想
[00:33.35]忘了你
[00:39.43]孤單魂
[00:41.51]隨風盪
[00:43.57]誰去笑
[00:45.87]痴情郎
[00:48.03]這紅塵的戰場
[00:52.95]千軍萬馬有誰能稱王
[01:01.69]過情關
[01:06.00]誰敢闖
[01:10.42]望明月
[01:15.62]心悲涼
[01:19.13]千古恨
[01:23.45]輪回嘗
[01:27.76]眼一閉
[01:32.71]誰最狂
[01:38.90]這世道的無常
[01:43.23]注定敢愛的人一生傷
[02:07.33]月光色
[02:09.20]女子香
[02:11.49]淚斷劍
[02:13.58]情多長
[02:15.80]有多痛
[02:17.87]無字想
[02:20.23]忘了你
[02:26.21]孤單魂
[02:28.20]隨風盪
[02:30.56]誰去笑
[02:32.64]痴情郎
[02:34.94]這紅塵的戰場
[02:39.70]千軍萬馬有誰能稱王
[02:48.65]過情關
[02:52.66]誰敢闖
[02:57.34]望明月
[03:02.44]心悲涼
[03:05.97]千古恨
[03:09.99]輪回嘗
[03:14.67]眼一閉
[03:19.95]誰最狂
[03:30.06]過情關
[03:34.34]誰敢闖
[03:38.78]望明月
[03:43.92]心悲涼
[03:47.58]千古恨
[03:51.50]輪回嘗
[03:55.96]眼一閉
[04:01.51]誰最狂
[04:07.21]這世道的無常
[04:21.34]注定敢愛的人一生傷
View Lyric

 

Java源代碼:

  1 import java.io.BufferedReader;
  2 import java.io.File;
  3 import java.io.FileInputStream;
  4 import java.io.InputStreamReader;
  5 import java.util.ArrayList;
  6 import java.util.HashMap;
  7 import java.util.List;
  8 import java.util.Map;
  9 import java.util.Map.Entry;
 10 import java.util.regex.Matcher;
 11 import java.util.regex.Pattern;
 12 
 13 public class TestLRC {
 14 
 15     public static void main(String[] args) {
 16         String path = "D:\\a.lrc"; // 歌詞文件路徑
 17         TestLRC lrc = new TestLRC();
 18         List<Map<Long, String>> list = lrc.parse(path);
 19         lrc.printLrc(list);
 20     }
 21 
 22     /**
 23      * 解析LRC歌詞文件
 24      * 
 25      * @param path
 26      *            lrc文件路徑
 27      * @return
 28      */
 29     private List<Map<Long, String>> parse(String path) {
 30         // 存儲所有歌詞信息的容器
 31         List<Map<Long, String>> list = new ArrayList<Map<Long, String>>();
 32         try {
 33             // String encoding = "utf-8"; // 字符編碼,若與歌詞文件編碼不符將會出現亂碼
 34             String encoding = "GBK";
 35             File file = new File(path);
 36             if (file.isFile() && file.exists()) { // 判斷文件是否存在
 37                 InputStreamReader read = new InputStreamReader(
 38                         new FileInputStream(file), encoding);
 39                 BufferedReader bufferedReader = new BufferedReader(read);
 40                 String regex = "\\[(\\d{1,2}):(\\d{1,2}).(\\d{1,2})\\]"; // 正則表達式
 41                 Pattern pattern = Pattern.compile(regex); // 創建 Pattern 對象
 42                 String lineStr = null; // 每次讀取一行字符串
 43                 while ((lineStr = bufferedReader.readLine()) != null) {
 44                     Matcher matcher = pattern.matcher(lineStr);
 45                     while (matcher.find()) {
 46                         // 用於存儲當前時間和文字信息的容器
 47                         Map<Long, String> map = new HashMap<Long, String>();
 48                         // System.out.println(m.group(0)); // 例:[02:34.94]
 49                         // [02:34.94] ----對應---> [分鍾:秒.毫秒]
 50                         String min = matcher.group(1); // 分鍾
 51                         String sec = matcher.group(2); //
 52                         String mill = matcher.group(3); // 毫秒,注意這里其實還要乘以10
 53                         long time = getLongTime(min, sec, mill + "0");
 54                         // 獲取當前時間的歌詞信息
 55                         String text = lineStr.substring(matcher.end());
 56                         map.put(time, text); // 添加到容器中
 57                         list.add(map);
 58                     }
 59                 }
 60                 read.close();
 61                 return list;
 62             } else {
 63                 System.out.println("找不到指定的文件:" + path);
 64             }
 65         } catch (Exception e) {
 66             System.out.println("讀取文件出錯!");
 67             e.printStackTrace();
 68         }
 69         return null;
 70     }
 71 
 72     /**
 73      * 將以字符串形式給定的分鍾、秒鍾、毫秒轉換成一個以毫秒為單位的long型數
 74      * 
 75      * @param min
 76      *            分鍾
 77      * @param sec
 78      *            秒鍾
 79      * @param mill
 80      *            毫秒
 81      * @return
 82      */
 83     private long getLongTime(String min, String sec, String mill) {
 84         // 轉成整型
 85         int m = Integer.parseInt(min);
 86         int s = Integer.parseInt(sec);
 87         int ms = Integer.parseInt(mill);
 88 
 89         if (s >= 60) {
 90             System.out.println("警告: 出現了一個時間不正確的項 --> [" + min + ":" + sec + "."
 91                     + mill.substring(0, 2) + "]");
 92         }
 93         // 組合成一個長整型表示的以毫秒為單位的時間
 94         long time = m * 60 * 1000 + s * 1000 + ms;
 95         return time;
 96     }
 97 
 98     /**
 99      * 打印歌詞信息
100      */
101     private void printLrc(List<Map<Long, String>> list) {
102         if (list == null || list.isEmpty()) {
103             System.out.println("沒有任何歌詞信息!");
104         } else {
105             for (Map<Long, String> map : list) {
106                 for (Entry<Long, String> entry : map.entrySet()) {
107                     System.out.println("時間:" + entry.getKey() + "  \t歌詞:"
108                             + entry.getValue());
109                 }
110             }
111         }
112     }
113 }
114  

 

 

解析結果:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM