Java使用正则表达式解析LRC歌词文件
2016-07-09 22:19
886 查看
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
示例歌词:
View Lyric
Java源代码:
解析结果:
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源代码:
import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.regex.Matcher; import java.util.regex.Pattern; public class TestLRC { public static void main(String[] args) { String path = "D:\\a.lrc"; // 歌词文件路径 TestLRC lrc = new TestLRC(); List<Map<Long, String>> list = lrc.parse(path); lrc.printLrc(list); } /** * 解析LRC歌词文件 * * @param path * lrc文件路径 * @return */ private List<Map<Long, String>> parse(String path) { // 存储所有歌词信息的容器 List<Map<Long, String>> list = new ArrayList<Map<Long, String>>(); try { // String encoding = "utf-8"; // 字符编码,若与歌词文件编码不符将会出现乱码 String encoding = "GBK"; File file = new File(path); if (file.isFile() && file.exists()) { // 判断文件是否存在 InputStreamReader read = new InputStreamReader( new FileInputStream(file), encoding); BufferedReader bufferedReader = new BufferedReader(read); String regex = "\\[(\\d{1,2}):(\\d{1,2}).(\\d{1,2})\\]"; // 正则表达式 Pattern pattern = Pattern.compile(regex); // 创建 Pattern 对象 String lineStr = null; // 每次读取一行字符串 while ((lineStr = bufferedReader.readLine()) != null) { Matcher matcher = pattern.matcher(lineStr); while (matcher.find()) { // 用于存储当前时间和文字信息的容器 Map<Long, String> map = new HashMap<Long, String>(); // System.out.println(m.group(0)); // 例:[02:34.94] // [02:34.94] ----对应---> [分钟:秒.毫秒] String min = matcher.group(1); // 分钟 String sec = matcher.group(2); // 秒 String mill = matcher.group(3); // 毫秒,注意这里其实还要乘以10 long time = getLongTime(min, sec, mill + "0"); // 获取当前时间的歌词信息 String text = lineStr.substring(matcher.end()); map.put(time, text); // 添加到容器中 list.add(map); } } read.close(); return list; } else { System.out.println("找不到指定的文件:" + path); } } catch (Exception e) { System.out.println("读取文件出错!"); e.printStackTrace(); } return null; } /** * 将以字符串形式给定的分钟、秒钟、毫秒转换成一个以毫秒为单位的long型数 * * @param min * 分钟 * @param sec * 秒钟 * @param mill * 毫秒 * @return */ private long getLongTime(String min, String sec, String mill) { // 转成整型 int m = Integer.parseInt(min); int s = Integer.parseInt(sec); int ms = Integer.parseInt(mill); if (s >= 60) { System.out.println("警告: 出现了一个时间不正确的项 --> [" + min + ":" + sec + "." + mill.substring(0, 2) + "]"); } // 组合成一个长整型表示的以毫秒为单位的时间 long time = m * 60 * 1000 + s * 1000 + ms; return time; } /** * 打印歌词信息 */ private void printLrc(List<Map<Long, String>> list) { if (list == null || list.isEmpty()) { System.out.println("没有任何歌词信息!"); } else { for (Map<Long, String> map : list) { for (Entry<Long, String> entry : map.entrySet()) { System.out.println("时间:" + entry.getKey() + " \t歌词:" + entry.getValue()); } } } } }
解析结果:
相关文章推荐
- 树状数组Binary Indexed Trees详解与Java实现
- Java Web学习(2):静态网页与动态网页
- Java反射机制
- 繁简体(GB-Big5)字符串互转的JAVA方式实现
- 繁简体(GB<=>Big5)字符串互转的JAVA方式实现
- java编码与解码
- Java设计模式(学习整理)----装饰模式
- Windows下设置java环境变量
- java常见错误----集结号
- 在配置spring的数据源时遇到的奇葩错误
- Java Web学习(1):Web应用程序与Web服务器
- Java-1.7新特性之文件路径
- java笔记(一)java的反射机制
- 管理 Java 类路径 (Windows)
- Java之多线程
- 初识Struts2
- java基础教程11:线程和线程间的同步
- RxJava 并发之数据流发射太快如何办
- 如何理解和使用Java package包
- eclipse快捷键大全