正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表通常被用来检索、替换那些符合某个模式(规则)的文本。

正则表达式的特点:
- 正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串
- 灵活性、逻辑性和功能性非常强
- 可以迅速地用极简单的方式达到字符串的复杂控制
- 使用广泛,很大部分的编译器/编辑器支持正则表达式

常见作用:
- 用作 过滤 / 匹配 给定的字符串是否符合特定规则
- 可以通过正则表达式,从字符串中获取我们想要的特定部分

关于正则表达式的基础概念和学习可以参考网站:
http://deerchao.net/tutorials/regex/regex.htm
http://www.runoob.com/regexp/regexp-tutorial.html
http://www.jb51.net/tools/zhengze.html
里面教程随便一个就能入门使用正则表达式

今天我所记录的是数据库结业作业中遇到的问题 LRC歌词解析 ,各种音乐播放器都存在解码器的概念,解码器越强所支持的格式越多,甚至部分程序有自己的一套音乐/歌词格式,比如酷狗的KRC等。
MP3/LRC 格式比较普遍,所以选择了LRC做解析练手

首先分析LRC歌词的格式:

一. 标识标签,其格式为“[标识名:值]”主要包含以下预定义的标签:

[ar:歌手名]
[ti:歌曲名]
[al:专辑名]
[by:编辑者(指lrc歌词的制作人)]
[offset:时间补偿值] (其单位是毫秒,正值表示整体提前,负值相反。这是用于总体调整显示快慢的,但多数的MP3可能不会支持这种标签)

二. 是时间标签形式为:
[mm:ss] [分钟数::秒钟数]
[mm:ss.ff] [分钟数:秒钟数.百分之一秒数]

时间标签需位于某行歌词中的句首部分,数字一般为非负整数,一行歌词可以包含多个时间标签(比如歌词中的迭句部分)。当歌曲播放到达某一时间点时,MP3就会寻找对应的时间标签并显示标签后面的歌词文本,这样就完成了“歌词同步”的功能。

举例一个包含大部分样式的歌词:

[ti:依赖]             //——ti.=title,标题,即歌曲名
[ar:蔡健雅]           //——ar.=artist,艺术家,即歌手名
[al:MY SPACE]        //——al.=album,专辑,即歌曲被收录的专辑
[by:Chapter Chang]   //——by somebody,即LRC歌词文件的制作者
[offset:0]           //——补偿时值。500=0.5秒,正负值分别提前和延长相应的时间(其值多为500的倍数)
[01:34.68]说很简单
[00:38.50]但是做却很难
[00:53.00][01:43.88][02:11.23]虽然无所谓写在脸上/* 歌词不是完整的,只是为了方便理解*/

可以看到,在每行都存在 [xxxx:xxxx] xxxxxxxxxx 的固定格式
括号里的根据前缀可以区分 标题,歌手名,专辑,时间信息等,后面的则是对应时间显示的字符串

这里还可能存在一个编码的问题,有时用TXT格式打开存在歌词全在一行,没有分行的情况.
这是因为在windows下默认编码为/t/n才为回车.此时用写字板打开,或者改变系统字体编码可以解决问题.
不过读到程序中不用考虑,在QT中可以打开文件后,使用QTextStream读取再通过 >> 或者readLine
来一行一行的读取,也可以使用readAll直接一次性全读取至QString.

我在读取文件的时候还遇到过一个关于编码的问题,就是使用QString Url(//filename) 方式读取,结果因为QString中/是转义字符,需要//才能代替/,和数据库中存放的路径不同…..后来才知道,这个情况得用:

  • std::string filename.c_str()
  • R”(字符串字面量)
  • Qt自带的Qurl

读取了文件后,开始介绍解析LRC文件的主角 ——– 正则表达式啦~~

在QT5.9中和正则表达式相关的类有:

QRegExp        //这货算是元老级类了,十年前就存在了,但通过查阅资料貌似对他的评价不太好...
QRegExpValidator   //用于检查用于正则表达式的字符串,常用来作为限制Edit输入的限制器
QRegularExpression    //今天的主角,QT5.0新引入的正则表达式类
QRegularExpressionValidator    //和第二个一样的功能
QRegularExpressionMatch  //QRegExpValidator的补充 ,相当于QRegExp的.cap(),用于提取匹配到的字符串

关于 QRegularExpression 和 QRegularExpressionMatch 的使用可以参考博客:
http://blog.csdn.net/qq_33266987/article/details/71479671

刚才上面的例子,首先利用split(“\n”, QString::SkipEmptyParts)把歌词分为一行一行的
再对每行进行解析:
首先建立 QRegularExpression对象,并且可以直接利用构造函数输入匹配的正则表达式

  QRegularExpression rex("\\[(ar)?(ti)?(al)?(by)?(offset)?(\\d+)?:(\\d+)?(\\.\\d+)?(\\S+)?\\]");

我所需要的功能仅仅是 把时间和歌词 连接成对,存在一个结构对里,供歌词播放时发送change信号,根据一样的时间量触发对应歌词,所以这里可以这样来解析:

  1. 先匹配无关信息 (ar)?(ti)?(al)?(by)?(offset)?,如果前面的数值存在则直接过滤掉(当然,需要也可以很简单的存起来)
  2. 然后在中间匹配自己需要的信息 (\d+)?:(\d+)?(\.\d+)? 三个括号分别对应了mm:ss.ff
  3. 最后匹配无关信息,因为是\s+,所以如果放到前面点可能就直接把需要的时间给吃掉了

    正则表达式写完后,怎么得到应用呢? 因为要读取歌词的时间和文本,所以我使用了这样的方法读取:

 /*lrc_row是歌词行,开始我用split(\n)分割过,其实利用正则不分割也可以做到解析*/for(int i = 0; i < lrc_row.size(); i++)    {qDebug()<<"lrc_row["<<i<<"]:"<<lrc_row[i];   /*  输出该行歌词内容              */    Match = rex.match(lrc_row[i]);               /*  解析该行歌词                 */qint64 totalTime = 0;                        /*  存该行歌词对应时间点(单位:ms)  */QString currenttxt;                          /*  存放该行歌词内容              */if(Match.captured(6).isEmpty())      /*  如果匹配到的 分钟 字符串为空则直接跳过  */{ qDebug()<<"no have lrc";continue;}else{totalTime+=Match.captured(6).toInt() * 60000 + Match.captured(7).toInt() * 1000 + Match.captured(9) * 10;                    /*  计算该时间点毫秒数            */      currenttxt = QString(lrc_row[i]).right(QString(lrc_row[i]).length() - Match.capturedLength());                         /*   获取歌词文本          */qDebug()<<"lrc_time:"<<totalTime<<endl;         /*  显示时间       */qDebug()<<"lrc_txt:"<<currenttxt<<endl;         /*  显示歌词       */}   }

效果如下:

这里展现出的正则可能和大多没有接触过QT的人有点不一样,就和之前说的那样,QT中QString中的\是转义字符,需要\才能表达\的意思,所以把所有的\去掉一个就是平常见到的正则了~
我也是第一次接触正则,所以对正则也不是太了解,一起加油加油!

Qt正则表达式学习之LRC歌词解析器相关推荐

  1. [open source]Lrc歌词解析器发布

    Lrc歌词解析器发布 最近一段时间专心学习英语,主要是想提高听说能力.从网上下载了<走遍美国>的mp3来听,比较简单,基本上可以听懂.偶尔遇到一个句子比较生僻,我想重新听一遍,我的意思是仅 ...

  2. 用javaScript编写lrc歌词解析器

    如果想要了解如何编写的请继续往下看,如果只需要代码,请点击这里Github lrc歌词文件介绍 来先看一下以下歌词 Heart To Heart.lrc [ti:Heart To Heart] [ar ...

  3. 学会在Linux环境下用c语言多文件制作lrc歌词解析器

    效果: 需要掌握的知识 1. 链表的熟悉运用. 懂得在链表的插入,排序. 2. 学会Linux下基本命令指令. sudo apt-get install vim //下载vim sudo apt-ge ...

  4. 设计模式学习(四):基于Builder模式的歌词解析器

    一.前言 上篇文章(设计模式学习(三):生成器(Builder)模式)记录了 Builder 模式的具体内容,这次使用C语言来实现一个实际的例子--基于Builder模式的歌词解析器. 本文的示例来自 ...

  5. python歌词解析器

    python实现歌词解析器 今天掌握到了歌词解析器的python基础语法代码实现,个人觉得挺有意思,便展示出来分享分享 注:展示结果为每过相应的时间,输出端打印相应的歌词 import time #导 ...

  6. Python 歌词解析器 音乐与歌词同步播放

    python 歌词解析器 前言 歌词解析器,顾名思义就是在播放歌曲的时候,音乐播放器放到那一句就显示对应的歌词. *在 python中歌词解析器并不难写,运用 time模块来编写歌词解析器, time ...

  7. python 歌词解析器传奇 歌词音乐同时输出

    ''' 歌词解析器:把歌词按照时间节点进行显示. 1.把歌词进行解析切片处理,把时间转成对应的浮点数 2.使用字典将时间与歌词进行存储{时间:歌词} 3.循环自动打印歌词[结束循环的条件,key为No ...

  8. lrc 歌词解析项目

    lrc 歌词解析项目 步骤: 0.先上网查找lrc歌词的格式,链接http://baike.baidu.com/view/80650.htm ,分析歌词格式 1.下载歌词文件 2.将歌词文件内容 通过 ...

  9. 链表(数据结构)- LRC歌词解析播放示例

    ###链表与数组 链表和数组一样也是线性表的一种,所谓线性表是指零个或多个数据元素的序列,序列元素之间有明显的前驱后继关系. 但链表与数组不一样的是,链表是通过指针域串联起来的,而数组是通过一片连续的 ...

最新文章

  1. NAS存储对称和非对称结构之前的区别概述
  2. 怎样使用CSS3媒体查询(Media Queries)制作响应式网站
  3. python的面向对象编程学生成绩_python的类_面向对象编程
  4. 校验金额、大小写字母、大写字母、合法uri、email
  5. leetcode 994.腐烂的橘子
  6. 神经网络中的优化算法总结
  7. 中文实体命名识别工具使用汇总:Stanza、LAC、Ltp、Hanlp、foolnltk、NLTK、BosonNLP
  8. PP视频如何设置关闭的时候直接退出程序
  9. linux进程如何挂起自己,Linux Server HTTP进程每天挂起服务器
  10. docker下使用solr
  11. linux系统调用记录模块实验报告,华科操作系统实验报告(DOC)
  12. java 圆形碰撞箱_你会使用“碰撞箱”吗?5种你不知道的玩法 甚至能定位死亡方位...
  13. IMETool 输入法设置工具 十问十答
  14. PADS软件如何导出BOM
  15. Windows11安装安卓子系统WSA及安卓应用
  16. oracle 实现等额本息,【oracle存储过程】实现生成等额本息的还款计划
  17. mysql1041_mysql8 参考手册--错误代码1036、1041、1046
  18. 2020 年值得关注的20个区块链项目,来看看今年该把目光放在哪?
  19. oracle 查询数据库时区,[原创]数据库时区与操作系统不一致时的解决方法
  20. Git入门|Git的基本用法(一)

热门文章

  1. 人工智能理解的“噩梦”是什么样子?MIT上线“Nightmare”网站迎接万圣节
  2. 学在西电课程回放下载与进度拖动
  3. 卷积神经网络之AlexNet网络模型学习
  4. google suggest的实现
  5. 网络草根月赚3000的10种方法
  6. 华为mate40和苹果12pro参数对比 哪个好?看了这篇再决定
  7. 洛奇英雄转无法读取游戏服务器状态,《洛奇英雄传》服务器认证失败解决方法攻略...
  8. Js中数组的slice和splice方法
  9. System.NullReferenceException HResult=0x80004003 Message=未将对象引用设置到对象的实例。
  10. mysql学习之路---01