7,762
社区成员
发帖
与我相关
我的任务
分享
using System;
using System.Collections;
using System.Text.RegularExpressions;
using System.Text;
namespace LrcLoad
{
/// <summary>
/// LRC 的摘要说明。
/// </summary>
///
/**************************************************
* LRC类用到的
* lrc文件处理的歌词对象,用以存贮歌词和时间字段
* *********************************************/
public class lrcBox
{
public double Time;
public string Text;
public lrcBox()
{
}
public lrcBox(double time,string text)
{
this.Time=time;
this.Text=text;
}
}
//LRC类
public class LRC
{
public string lrcSoure;//LRC文件字符串
public string ar="";
public string ti="";
public string al="";
public string by="";
public int Length=0;
//余补时间
public double oTime=0;
//ArrayList用于存贮每句歌词对象
public ArrayList arrList=new ArrayList();
//LRC类构造函数,入口是LRC文件字符串
public LRC(string lrcFile)
{
lrcSoure=lrcFile;
lrcAddtoList();//LRC每句歌词都放到ArrayList,并且按歌词时间排序
}
public LRC()
{
}
/**************************************************
* 本过程从变量lrcSoure提取“题目,歌手”等信息。
*
* ***********************************************/
private void steLrcTi()
{
//提取ti
Regex reg = new Regex(@"\[ti:([^\[\]:]+)\]",RegexOptions.IgnoreCase);
if(reg.IsMatch(lrcSoure))
{
this.ti=reg.Matches(lrcSoure)[0].Groups[0].ToString();
}
reg=null;
//提取ar
reg = new Regex(@"\[ar:([^\[\]:]+)\]",RegexOptions.IgnoreCase);
if(reg.IsMatch(lrcSoure))
{
this.ar=reg.Matches(lrcSoure)[0].Groups[0].ToString();
}
reg=null;
//提取al
reg = new Regex(@"\[al:([^\[\]:]+)\]",RegexOptions.IgnoreCase);
if(reg.IsMatch(lrcSoure))
{
this.al=reg.Matches(lrcSoure)[0].Groups[0].ToString();
}
reg=null;
//提取by
reg = new Regex(@"\[by:([^\[\]:]+)\]",RegexOptions.IgnoreCase);
if(reg.IsMatch(lrcSoure))
{
this.by=reg.Matches(lrcSoure)[0].Groups[0].ToString();
}
reg=null;
//提取余补时间offset到oTime
reg= new Regex(@"\[offset\:(\-?\d+)\]",RegexOptions.IgnoreCase);
if(reg.IsMatch(lrcSoure))
{
oTime=double.Parse( reg.Matches(lrcSoure)[0].Groups[1].ToString())/1000;
}
// if(Regex.IsMatch(lrcSoure,@"\[ar:([^\[\]:]+)\]",RegexOptions.IgnoreCase))
//{
// this.ar=Regex.Match(lrcSoure,@"\[ar:([^\[\]:]+)\]",RegexOptions.IgnoreCase)[0].Groups[0].ToString();
//}
}
/***************************************************************
*
* 删除注释
* 入口:LRC文件字符串
* 中间处理:把一句中含有多个时间标签的句子,拆分成一句歌词只含有一个时间标签的形式。
* 出口:不再含有其他信息的,纯粹的歌词及其对应的时间,每句歌词是以回车符换行符分隔的
* *************************************************************/
private string delNotes(string lrcS)
{
StringBuilder s=new StringBuilder();
//修正
lrcS+="\n";
string str1;
int j;
//正则:匹配一个LRC句子,句子可能含有多个时间信息(歌中同一句词会有多次唱到)
Regex reg = new Regex(@"\[\d+\:[\d\.]+\](.*)[\n\x0d\x0a]",RegexOptions.IgnoreCase);
//正则:匹配一个LRC时间标签
Regex SubReg=new Regex(@"\[\d+\:[\d\.]+\]",RegexOptions.IgnoreCase);
if(reg.IsMatch(lrcS))
{
//保存句子匹配集合到变量c
MatchCollection c = reg.Matches(lrcS);
//分开处理每一句
for(int i=0;i<c.Count;i++)
{
str1=c[i].Value.ToString();
if(SubReg.IsMatch(str1))
{
//从一句中,提取每个时间信息
MatchCollection subc=SubReg.Matches(str1);
for(j=0;j<subc.Count;j++)
{
//去掉所有时间标签,以得到歌词
str1=str1.Replace(subc[j].Value.ToString(),"");
}
for(j=0;j<subc.Count;j++)
{
//每个时间标签,都加上歌词,然后合成一个只有一个时间标签,对应一句歌词的LRC字符串
s.Append(subc[j].Value.ToString()+str1);
}
}
}
}
reg=null;
return s.ToString();
}
/********************************************************
* 重载IComparer.Compare,以进行arrList.Sort(排序)
* ******************************************************/
public class myRClass : IComparer
{
// Calls CaseInsensitiveComparer.Compare with the parameters reversed.
int IComparer.Compare( Object x, Object y )
{
//以时间Timer作为比较因子
return( (new CaseInsensitiveComparer()).Compare( ((lrcBox)x).Time,((lrcBox)y).Time ) );
}
}
/****************************************************
* 把LRC字符串加入到ArrayList并排列
* LRC从变量this.lrcSoure得到
* ***************************************************/
public void lrcAddtoList()
{
steLrcTi();//提取“题目,歌手”等信息
string str= delNotes(this.lrcSoure);//变量str不再含有其他信息的,纯粹的歌词及其对应的时间,每句歌词是以回车符换行符分隔的
//正则:匹配一句歌词,同时有时间和歌词的子匹配
Regex reg=new Regex(@"\[(\d+)\:([\d\.]+)\](.*)[\n\x0d\x0a]",RegexOptions.IgnoreCase);
if(reg.IsMatch(str))
{
MatchCollection c=reg.Matches(str);
for(int i=0;i<c.Count;i++)
{
//把每一句歌词分别放到ArrayList中去
//c[i].Groups[1]匹配时间信息中的分钟,c[i].Groups[2]匹配秒,c[i].Groups[3]匹配歌词。减去oTime是为了修正时间
arrList.Add(new lrcBox(int.Parse(c[i].Groups[1].ToString())*60+double.Parse(c[i].Groups[2].ToString())-oTime,c[i].Groups[3].ToString()));
}
}
this.Length=arrList.Count;
//排序,按照Time的数进行排列顺序
IComparer myComparer = new myRClass();
arrList.Sort(myComparer );
}
//------------------外部接口
/***********************************************************
* 本函数实现从ArrayList中提取出歌词
* *********************************************************/
public string GetSoundText()
{
StringBuilder s=new StringBuilder();
for(int i=0;i<this.Length;i++)
{
s.Append(((lrcBox)arrList[i]).Text+"\n");
}
return s.ToString();
}
//-------------------
//------------------
}
}