Swift 给一段话分句,或将一句话关键词分组

场景

目前正在做阅读器听书功能,集成了百度语音后,每次要给语音SDK传入一句话,然后得到语音。但是有长度限制。为了语音流畅,需要将一章文字按句分组,之后管理一个队列数组,用于语音功能。

如何给一段话分句

实践一:使用 Stingcomponents(separatedBy: ) 方法

其实最开始是想通过正则表达式分组,最终未能实现。之后使用该方法。其实分组不仅仅可以传入单个字符,也能传入一个字符组:

        components(separatedBy: <#T##StringProtocol#>)
        components(separatedBy: <#T##CharacterSet#>)

这个也是我最初采用的方法。但是之后发现存在比较严重的问题,并且并未解决。

存在问题:首先,分组后的语句是不包含作为分隔符的标点符号的,这样对于阅读器切页时每页的 Range 就产生了影响,没法精确判断读到该页末尾时翻页、翻章。其次,阅读文字时需要字体高亮,但是通过该方法分组后的语句,对于作为分隔符的标点符号,如果紧邻其他符号,其他符号为氛围下一句,最典型的就是 。” ,分组后,下引号会分到下一句,明显很难看。

实现代码如下:

       let str = "我说:“这是一句话。”而且按照现在的情况来看,这个奥术还是特别加强了稳固性和构成速度!顷刻之间就要爆发了。“混蛋……居然是这样的陷阱…”女法师脸上浮现出了悲愤,无奈,绝望。"
        let matchs = str.components(separatedBy: CharacterSet.init(charactersIn: " 。!?;\n "))
        matchs.forEach { (s) in
            print("🌞 --- \(s)")
        }

控制台输出:

🌞 --- 我说:“这是一句话
🌞 --- ”而且按照现在的情况来看,这个奥术还是特别加强了稳固性和构成速度
🌞 --- 顷刻之间就要爆发了
🌞 --- “混蛋……居然是这样的陷阱…”女法师脸上浮现出了悲愤,无奈,绝望
🌞 --- 

存在问题显而易见,尤其是需要这句话高亮时,问题更明显。由此,查资料时找到了第二种方法。

实践二:采用原生 API 接口 CFStringTokenizer

CFStringTokenizer功能很强大,之前也从未使用过,这里也只是通过查询一些博客,采用了自己需要的一点功能。

        let str = "我说:“这是一句话。”而且按照现在的情况来看,这个奥术还是特别加强了稳固性和构成速度!顷刻之间就要爆发了。“混蛋……居然是这样的陷阱…”女法师脸上浮现出了悲愤,无奈,绝望。"
        let ref = CFStringTokenizerCreate(nil, str as CFString, CFRangeMake(0, str.lenght), kCFStringTokenizerUnitSentence, nil)
        CFStringTokenizerAdvanceToNextToken(ref)
        var range: CFRange
        range = CFStringTokenizerGetCurrentTokenRange(ref)
        // 循环
        var sentence = ""
        var sentences = [String]()
        while range.length > 0 {
            sentence = str.substring(NSMakeRange(range.location, range.length))
            sentences.append(sentence)
            CFStringTokenizerAdvanceToNextToken(ref)
            range = CFStringTokenizerGetCurrentTokenRange(ref)
            print("🦁    \(sentence)")
        }

控制台输出:

🦁    我说:“这是一句话。”
🦁    而且按照现在的情况来看,这个奥术还是特别加强了稳固性和构成速度!
🦁    顷刻之间就要爆发了。“
🦁    混蛋……居然是这样的陷阱…”女法师脸上浮现出了悲愤,无奈,绝望。

是不是符合预期的结果直接就出来了。。暂时效果如下图:


听书

如果修改属性 kCFStringTokenizerUnitSentencekCFStringTokenizerUnitWord ,就是按照关键词分组了。其实这个属性还有其他各种设置,具体使用时可以根据需要修改。
另外,关键词分组效果类似:

🦁    我
🦁    说
🦁    这
🦁    是
🦁    一
🦁    句
🦁    话
🦁    而且
🦁    按照
🦁    现在
🦁    的

如何暂停倒计时

这个也是刚刚用到的一个方法。一旦 timer.invalidate() 后,并不能在开启了。下面是一个简单的计时器实现:

    // MARK: - 计时器
    @IBOutlet weak var timeView: UIView!
    @IBOutlet weak var timeLabel: UILabel!
    private var countdownTimer: Timer?
    private var durtion: Int = 0
    // 开始
    @IBAction func startTimerAction(_ sender: UIButton) {
        if countdownTimer == nil {
            countdownTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(countdown), userInfo: nil, repeats: true)
        }
        durtion = 0
    }
    // 暂停
    @IBAction func pauseTimerAction(_ sender: UIButton) {
        countdownTimer?.fireDate = Date.distantFuture
    }
    // 继续
    @IBAction func resumeTimerAction(_ sender: UIButton) {
        countdownTimer?.fireDate = Date.distantPast
    }
    // 停止
    @IBAction func stopTimerAction(_ sender: UIButton) {
        countdownTimer?.invalidate()
        countdownTimer = nil
    }
    // 计时
    @objc private func countdown() {
        durtion += 1
        let delaySeconds = 30 * 60 - durtion
        let minutes = delaySeconds / 60
        let seconds = delaySeconds % 60
        let timeStr = String(format: "%02d:%02d", arguments: [minutes, seconds])
        timeLabel.text = timeStr
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,295评论 6 512
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,928评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,682评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,209评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,237评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,965评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,586评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,487评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,016评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,136评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,271评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,948评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,619评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,139评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,252评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,598评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,267评论 2 358

推荐阅读更多精彩内容