排序和正则表达式的应用
题目为了实现一边播放歌曲,一边同步显示歌词,很多播放器会借助 lrc 文件。 播放器需要做两件事: [ti:两只老虎]
[ar:歌者盟]
[al:歌者盟翻唱专辑]
[by:]
[offset:700]
[00:00.74]两只老虎
[00:08.34][00:24.26][00:40.26][00:56.23]两只老虎两只老虎 跑得快跑得快
[00:16.39][00:32.37][00:48.16][01:04.37]一只没有耳朵 一只没有尾巴
[00:20.28][00:36.19][00:52.29][01:08.15]真奇怪 真奇怪
[00:05.52][00:39.83][01:12.28]
展开成 [ti:两只老虎]
[ar:歌者盟]
[al:歌者盟翻唱专辑]
[by:]
[offset:700]
[00:00.74]两只老虎
[00:05.52]
[00:08.34]两只老虎两只老虎 跑得快跑得快
[00:16.39]一只没有耳朵 一只没有尾巴
[00:20.28]真奇怪 真奇怪
[00:24.26]两只老虎两只老虎 跑得快跑得快
[00:32.37]一只没有耳朵 一只没有尾巴
[00:36.19]真奇怪 真奇怪
[00:39.83]
[00:40.26]两只老虎两只老虎 跑得快跑得快
[00:48.16]一只没有耳朵 一只没有尾巴
[00:52.29]真奇怪 真奇怪
[00:56.23]两只老虎两只老虎 跑得快跑得快
[01:04.37]一只没有耳朵 一只没有尾巴
[01:08.15]真奇怪 真奇怪
[01:12.28]
实现思路 储备知识: val wsnumPatten = """s+[0-9]+s+""".r
val m1 = wsnumPatten.findFirstIn("10 x,20 y")
//m1: Option[String] = Some( 20 )
这边因为10前面没有一个满足 val wsnumPatten = """s+[0-9]+s+""".r
val m1 = wsnumPatten.findPrefixOf("10 x,20 y")
val m2 = wsnumPatten.findPrefixOf(" 10 x,20 y")
//m1: Option[String] = None
//m2: Option[String] = Some( 10 )
val wsnumPatten = """s+[0-9]+s+""".r
val m1 = wsnumPatten.replaceFirstIn("10 x,20 y","ctao")
val m2 = wsnumPatten.replaceAllIn(" 10 x,"ctao")
//m1: String = 10 x,ctaoy
//m2: String = ctaox,ctaoy
val timer = """([dd:dd.dd])(.*)""".r
for (timer(time,content) ←
timer.findAllIn("[00:36.19]真奇怪 真奇怪"))
println(s"time:$time,content:$content")
//time:[00:36.19],content:真奇怪 真奇怪
显然,我们用第一个括号匹配了时间标签,第二个匹配了内容 而排序:主要就是一个实现了 case class Line(time: String,content: String) extends Ordered[Line] {
override def compare(that: Line): Int =
if (stringTime2Double(time) > stringTime2Double(that.time))
1
else if (stringTime2Double(time) < stringTime2Double(that.time))
-1
else
0
private def stringTime2Double(time: String): Double = {
val timeFormat = """[dd:dd.dd]""".r
assert(timeFormat.findAllIn(time).nonEmpty)
time.mkString
.split("[")(1).split("]")(0)
.replace(":","")
.replace(".","")
.toDouble
}
其实这边string2Double有点多余,后面会优化掉,这边主要就是实现了Ordered,因为在调用集合类的Sorted方法时需要 def sorted[B >: A](implicit ord : scala.math.Ordering[B])
基本储备够了我们看第一种实现: package ctao.jan
import scala.collection.mutable.ArrayBuffer
import scala.io.Source
/** * Created by ctao on 16-1-14. */
object SongTest extends App {
case class Line(time: String,"")
.toDouble
}
}
def inputLrc(path: String) = {
val contentBuffer = ArrayBuffer[Line]()
val titleBuffer = ArrayBuffer[String]()
val timers = """([dd:dd.dd].+])(.*)""".r
val timer = """([dd:dd.dd])(.*)""".r
val timeFormat = """[dd:dd.dd]""".r
for (line ← Source.fromFile(path).getLines()) {
line match {
case timers(times,content) ?
for (time ← timeFormat.findAllIn(times))
contentBuffer += Line(time,content)
case timer(time,content) ?
contentBuffer += Line(time,content)
case title: String ?
titleBuffer += title
}
}
(titleBuffer,contentBuffer)
}
def expend(path: String) = {
val (titleBuffer,contentBuffer) = inputLrc(path)
titleBuffer.foreach(println)
for(x ← contentBuffer.sorted){
println(s"${x.time}${x.content}")
}
}
expend("lrc")
}
可以是可以了,但问题有几点: package ctao.jan
import scala.io.Source
/** * Created by ctao on 16-1-14. */
object SongTest extends App {
def inputLrc(path: String) = {
var contentList = List[(String,String)]()
var titleList = List[String]()
val timers = """([dd:dd.dd].+])(.*)""".r
val timer = """([dd:dd.dd])(.*)""".r
val timeFormat = """[dd:dd.dd]""".r
for (line ← Source.fromFile(path).getLines()) {
line match {
case timers(times,content) ?
for (time ← timeFormat.findAllIn(times))
contentList :+= Tuple2(time,content) ?
contentList :+= Tuple2(time,content)
case title: String ?
titleList :+= title
}
}
(contentList,titleList)
}
def expend(path: String) = {
val (contentList,titleList) = inputLrc(path)
titleList.foreach(println)
for (x ← contentList.sorted) {
println(s"${x._1}${x._2}")
}
}
expend("lrc")
}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |