C#解析Lrc歌词文件过程详解

看到很多人解析歌词文件时写了一大片的字符处理代码,而且看得不是很明白,所以自己研究了一下,
 首先来了解下Lrc文件
 时间格式:
 1、标准格式: [分钟:秒.毫秒] 歌词
 注释:括号、冒号、点号全都要求英文输入状态;
 2、其他格式①:[分钟:秒] 歌词;
 3、其他格式②:[分钟:秒:毫秒] 歌词,与标准格式相比,秒后边的点号被改成了冒号。

标准格式:
 其格式为"[标识名:值]"。大小写等价。以下是预定义的标签。
[ar:艺人名]
[ti:曲名]
[al:专辑名] 
[by:编者(指编辑LRC歌词的人)] 
[offset:时间补偿值] 其单位是毫秒,正值表示整体提前,负值相反。这是用于总体调整显示快慢的。
标准好啊,我就按照标准来做了

 public class Lrc
 {
  /// <summary>
  /// 歌曲
  /// </summary>
  public string Title { get; set; }
  /// <summary>
  /// 艺术家
  /// </summary>
  public string Artist { get; set; }
  /// <summary>
  /// 专辑
  /// </summary>
  public string Album { get; set; }
  /// <summary>
  /// 歌词作者
  /// </summary>
  public string LrcBy { get; set; }
  /// <summary>
  /// 偏移量
  /// </summary>
  public string Offset { get; set; }

  /// <summary>
  /// 歌词
  /// </summary>
  public Dictionary<double, string> LrcWord = new Dictionary<double, string>();

  /// <summary>
  /// 获得歌词信息
  /// </summary>
  /// <param name="LrcPath">歌词路径</param>
  /// <returns>返回歌词信息(Lrc实例)</returns>
  public static Lrc InitLrc(string LrcPath)
  {
   Lrc lrc = new Lrc();
   using (FileStream fs = new FileStream(LrcPath, FileMode.Open, FileAccess.Read, FileShare.Read))
   {
    string line;
    using (StreamReader sr = new StreamReader(fs, Encoding.Default))
    {
     while ((line = sr.ReadLine()) != null)
     {
      if (line.StartsWith("[ti:"))
      {
       lrc.Title = SplitInfo(line);
      }
      else if (line.StartsWith("[ar:"))
      {
       lrc.Artist = SplitInfo(line);
      }
      else if (line.StartsWith("[al:"))
      {
       lrc.Album = SplitInfo(line);
      }
      else if (line.StartsWith("[by:"))
      {
       lrc.LrcBy = SplitInfo(line);
      }
      else if (line.StartsWith("[offset:"))
      {
       lrc.Offset = SplitInfo(line);
      }
      else
      {
       Regex regex = new Regex(@"\[([0-9.:]*)\]+(.*)", RegexOptions.Compiled);
       MatchCollection mc = regex.Matches(line);
       double time = TimeSpan.Parse("00:" + mc[0].Groups[1].Value).TotalSeconds;
       string word = mc[0].Groups[2].Value;
       lrc.LrcWord.Add(time, word);
      }
     }
    }
   }
   return lrc;
  }

  /// <summary>
  /// 处理信息(私有方法)
  /// </summary>
  /// <param name="line"></param>
  /// <returns>返回基础信息</returns>
  static string SplitInfo(string line)
  {
   return line.Substring(line.IndexOf(":") + 1).TrimEnd(']');
  }
 }

一行代码:Lrc lrc= Lrc.InitLrc("test.lrc");

我将分离好的歌词放入了Dictionary<double, string>里,当然也可以直接用数组存,格式就要看实际的用途了,把这些都交给TimeSpan来做吧。 
测试:

很久以前有人提出了这个问题:一行歌词里面有多个时间会报错,这么久了也没见人把好的方案提供出来,今天我花了点时间,修改了下,下面是获取歌词方法

/// <summary>
  /// 获得歌词信息
  /// </summary>
  /// <param name="LrcPath">歌词路径</param>
  /// <returns>返回歌词信息(Lrc实例)</returns>
  public static Lrc InitLrc(string LrcPath)
  {
   Lrc lrc = new Lrc();
   Dictionary<double, string> dicword = new Dictionary<double, string>();
   using (FileStream fs = new FileStream(LrcPath, FileMode.Open, FileAccess.Read, FileShare.Read))
   {
    string line;
    using (StreamReader sr = new StreamReader(fs, Encoding.Default))
    {
     while ((line = sr.ReadLine()) != null)
     {
      if (line.StartsWith("[ti:"))
      {
       lrc.Title = SplitInfo(line);
      }
      else if (line.StartsWith("[ar:"))
      {
       lrc.Artist = SplitInfo(line);
      }
      else if (line.StartsWith("[al:"))
      {
       lrc.Album = SplitInfo(line);
      }
      else if (line.StartsWith("[by:"))
      {
       lrc.LrcBy = SplitInfo(line);
      }
      else if (line.StartsWith("[offset:"))
      {
       lrc.Offset = SplitInfo(line);
      }
      else
      {
       try
       {
        Regex regexword = new Regex(@".*\](.*)");
        Match mcw = regexword.Match(line);
        string word = mcw.Groups[1].Value;
        Regex regextime = new Regex(@"\[([0-9.:]*)\]", RegexOptions.Compiled);
        MatchCollection mct = regextime.Matches(line);
        foreach (Match item in mct)
        {
         double time = TimeSpan.Parse("00:" + item.Groups[1].Value).TotalSeconds;
         dicword.Add(time, word);
        }
       }
       catch
       {
        continue;
       }
      }
     }
    }
   }
   lrc.LrcWord = dicword.OrderBy(t => t.Key).ToDictionary(t => t.Key, p => p.Value);
   return lrc;
  }

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • c#实现flv解析详解示例

    先上效果图:   工具类 在解析的过程中,我们会和byte做各种运算,所以我定义了一个byte工具类ByteUtils: 复制代码 代码如下: using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.IO; namespace FLVParer.Utils{    class ByteUtils    {        public static uint Byt

  • asp.net C#生成和解析二维码的实例代码

    类库文件我们在文件最后面下载 [ThoughtWorks.QRCode.dll 就是类库] 使用时需要增加: 复制代码 代码如下: using ThoughtWorks.QRCode.Codec; using ThoughtWorks.QRCode.Codec.Data; using ThoughtWorks.QRCode.Codec.Util; 主要源代码: 1.生成二维码 复制代码 代码如下: QRCodeEncoder qrCodeEncoder = new QRCodeEncoder()

  • c#中XML解析文件出错解决方法

    1.内容中含有xml预定好的实体,如"<"和"&",对xml来说是禁止使用的,针对这种字符,解决方式是使用CDATA部件以"<![CDATA[" 标记开始,以"]]>"标记结束,是CDATA内部内容被解析器忽略.具体说明参考<XML CDATA是什么?>. 2.内容中含有低位非打印字符,解析时会报错:""(十六进制值 0x1D)是无效的字符.加载或保存XML时引发的异常

  • C#正则实现Ubb解析类的代码

    解析得到的代码能通过XHTML 1.0 STRICT验证; 包含了标题,链接,字体,对齐,图片,引用,列表等方面的功能.  Ubb.ReadMe.htm UBB代码说明 标题 [h1]标题一[/h1] 标题一 [h2]标题二[/h2] 标题二 [h1]标题三[/h1] 标题三 [h4]标题四[/h4] 标题四 [h5]标题五[/h5] 标题五 [h6]标题六[/h6] 标题六 链接 [url]www.unibetter.com[/url] unibetter.com [url]http://ww

  • 用C#来解析PDF文件

    1. 介绍 这个项目让你可以去读取并解析一个PDF文件,并将其内部结构展示出来. PDF文件的格式标准文档可以从Adobe那儿获取到. 这个项目基于"PDF指南,第六版,Adobe便携文档格式1.7 2006年11月". 它是一个恐怕有1310页的大部头. 本文提供了对这份文档的简洁概述. 与此相关的项目定义了用来读取和解析PDF文件的C#类. 为了测试这些类,附带的测试程序PdfFileAnalyzer让你可以去读取一个PDF文件,分析它并展示和保存结果. 程序将PDF文件分割成单独

  • xml 封装与解析(javascript和C#中)

    1.xml的解析(javascript中): 具体代码如下,解析的结果root为Dom树. 复制代码 代码如下: if (window.ActiveXObject){ var doc=new ActiveXObject("Microsoft.XMLDOM"); doc.async="false"; doc.loadXML(strXml); }else{ var parser=new DOMParser(); var doc=parser.parseFromStrin

  • C#解析JSON实例

    本文以实例形式讲述了C#解析JSON的方法,C#封装了对XML和JSON解析的类库,使用相当方便!具体用法如下: 1.主要用到的类: 主要用到了JavaScriptSerializer类,该类在System.Web.Script.Serialization命名空间(在System.Web.Extensions.dll 中),需要把.NET版本修改为 .NET Framework 4(默认是.NET Framework 4 Client Profile)才能在Add Reference的 .NET

  • C# 解析 Excel 并且生成 Csv 文件代码分析

    今天工作中遇到一个需求,就是获取 excel 里面的内容,并且把 excel 另存为 csv,因为本人以前未接触过,所以下面整理出来的代码均来自网络,具体参考链接已丢失,原作者保留所有权利! 例子: 复制代码 代码如下: using System; using System.Data; namespace ExportExcelToCode {     class ExcelOperater     {         public void Operater()         {      

  • C#下解析HTML的两种方法介绍

    在搜索引擎的开发中,我们需要对Html进行解析.本文介绍C#解析HTML的两种方法.AD: 在搜索引擎的开发中,我们需要对网页的Html内容进行检索,难免的就需要对Html进行解析.拆分每一个节点并且获取节点间的内容.此文介绍两种C#解析Html的方法. C#解析Html的第一种方法:用System.Net.WebClient下载Web Page存到本地文件或者String中,用正则表达式来分析.这个方法可以用在Web Crawler等需要分析很多Web Page的应用中.估计这也是大家最直接,

  • C#解析json文件的实现代码

    C# 解析 json JSON(全称为JavaScript Object Notation) 是一种轻量级的数据交换格式.它是基于JavaScript语法标准的一个子集. JSON采用完全独立于语言的文本格式,可以很容易在各种网络.平台和程序之间传输.JSON的语法很简单,易于人阅读和编写,同时也易于机器解析和生成. JSON与XML的比较 ◆可读性 JSON和XML的可读性相比较而言,由于XML提供辅助的标签,更加适合人阅读和理解.◆文件大小与传输 XML允许使用方便的标签,所以文件尺寸是要比

随机推荐