Qt正则表达式学习之LRC歌词解析器
正则表达式,又称规则表达式。(英语: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信号,根据一样的时间量触发对应歌词,所以这里可以这样来解析:
- 先匹配无关信息 (ar)?(ti)?(al)?(by)?(offset)?,如果前面的数值存在则直接过滤掉(当然,需要也可以很简单的存起来)
- 然后在中间匹配自己需要的信息 (\d+)?:(\d+)?(\.\d+)? 三个括号分别对应了mm:ss.ff
最后匹配无关信息,因为是\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歌词解析器相关推荐
- [open source]Lrc歌词解析器发布
Lrc歌词解析器发布 最近一段时间专心学习英语,主要是想提高听说能力.从网上下载了<走遍美国>的mp3来听,比较简单,基本上可以听懂.偶尔遇到一个句子比较生僻,我想重新听一遍,我的意思是仅 ...
- 用javaScript编写lrc歌词解析器
如果想要了解如何编写的请继续往下看,如果只需要代码,请点击这里Github lrc歌词文件介绍 来先看一下以下歌词 Heart To Heart.lrc [ti:Heart To Heart] [ar ...
- 学会在Linux环境下用c语言多文件制作lrc歌词解析器
效果: 需要掌握的知识 1. 链表的熟悉运用. 懂得在链表的插入,排序. 2. 学会Linux下基本命令指令. sudo apt-get install vim //下载vim sudo apt-ge ...
- 设计模式学习(四):基于Builder模式的歌词解析器
一.前言 上篇文章(设计模式学习(三):生成器(Builder)模式)记录了 Builder 模式的具体内容,这次使用C语言来实现一个实际的例子--基于Builder模式的歌词解析器. 本文的示例来自 ...
- python歌词解析器
python实现歌词解析器 今天掌握到了歌词解析器的python基础语法代码实现,个人觉得挺有意思,便展示出来分享分享 注:展示结果为每过相应的时间,输出端打印相应的歌词 import time #导 ...
- Python 歌词解析器 音乐与歌词同步播放
python 歌词解析器 前言 歌词解析器,顾名思义就是在播放歌曲的时候,音乐播放器放到那一句就显示对应的歌词. *在 python中歌词解析器并不难写,运用 time模块来编写歌词解析器, time ...
- python 歌词解析器传奇 歌词音乐同时输出
''' 歌词解析器:把歌词按照时间节点进行显示. 1.把歌词进行解析切片处理,把时间转成对应的浮点数 2.使用字典将时间与歌词进行存储{时间:歌词} 3.循环自动打印歌词[结束循环的条件,key为No ...
- lrc 歌词解析项目
lrc 歌词解析项目 步骤: 0.先上网查找lrc歌词的格式,链接http://baike.baidu.com/view/80650.htm ,分析歌词格式 1.下载歌词文件 2.将歌词文件内容 通过 ...
- 链表(数据结构)- LRC歌词解析播放示例
###链表与数组 链表和数组一样也是线性表的一种,所谓线性表是指零个或多个数据元素的序列,序列元素之间有明显的前驱后继关系. 但链表与数组不一样的是,链表是通过指针域串联起来的,而数组是通过一片连续的 ...
最新文章
- NAS存储对称和非对称结构之前的区别概述
- 怎样使用CSS3媒体查询(Media Queries)制作响应式网站
- python的面向对象编程学生成绩_python的类_面向对象编程
- 校验金额、大小写字母、大写字母、合法uri、email
- leetcode 994.腐烂的橘子
- 神经网络中的优化算法总结
- 中文实体命名识别工具使用汇总:Stanza、LAC、Ltp、Hanlp、foolnltk、NLTK、BosonNLP
- PP视频如何设置关闭的时候直接退出程序
- linux进程如何挂起自己,Linux Server HTTP进程每天挂起服务器
- docker下使用solr
- linux系统调用记录模块实验报告,华科操作系统实验报告(DOC)
- java 圆形碰撞箱_你会使用“碰撞箱”吗?5种你不知道的玩法 甚至能定位死亡方位...
- IMETool 输入法设置工具 十问十答
- PADS软件如何导出BOM
- Windows11安装安卓子系统WSA及安卓应用
- oracle 实现等额本息,【oracle存储过程】实现生成等额本息的还款计划
- mysql1041_mysql8 参考手册--错误代码1036、1041、1046
- 2020 年值得关注的20个区块链项目,来看看今年该把目光放在哪?
- oracle 查询数据库时区,[原创]数据库时区与操作系统不一致时的解决方法
- Git入门|Git的基本用法(一)
热门文章
- 人工智能理解的“噩梦”是什么样子?MIT上线“Nightmare”网站迎接万圣节
- 学在西电课程回放下载与进度拖动
- 卷积神经网络之AlexNet网络模型学习
- google suggest的实现
- 网络草根月赚3000的10种方法
- 华为mate40和苹果12pro参数对比 哪个好?看了这篇再决定
- 洛奇英雄转无法读取游戏服务器状态,《洛奇英雄传》服务器认证失败解决方法攻略...
- Js中数组的slice和splice方法
- System.NullReferenceException HResult=0x80004003 Message=未将对象引用设置到对象的实例。
- mysql学习之路---01