将大型混合数字和文本数字转换为Swift或Objective-C

时间:2019-04-04 00:08:34

标签: swift nsstring nscharacterset nsformatter

NSFormatter的spellout方法使您可以将单词转换为数字。 NSString的stringByReplacingOccurrencesOfString可以将字符串从1000转换为1000。还可以使用NSCharacterSet从字符串中选择整数。但是,我在如何将数字和字符串的混合(例如about 2.4 millioncomes to 5 hundred转换为数字)中苦苦挣扎。问题在于将“ 240万”与“关于”或其他文本区分开来。

将拼写说明应用于“ 240万”会产生2400000。但是,将其应用于“大约240万”会产生错误。

extension NSString {
    public var asNum: NSNumber {
       // let stringValue = String(value: self)
        let stringValue = self
        let formatter = NumberFormatter()
        formatter.isLenient = true
        formatter.numberStyle = .spellOut
        return formatter.number(from: stringValue as String) ?? -1
    }
}

如何仅隔离有效数字中的术语?

1 个答案:

答案 0 :(得分:1)

如果使用正则表达式,则可以仅提取带有数字表达式的字符串。假设多余的单词在开头(如您在评论中所述),您可以执行以下操作:

  • 使用正则表达式搜索数字表达式,在这种情况下,表达式是一个数字,后跟一个单词。 \d+(\.\d+)*\s+\w+
  • 检查是否已找到表达式range.location != NSNotFound
  • 将匹配项提取到String

您可以在代码中仅添加三行,它应该可以正常工作,如下所示:

extension NSString {
    public var asNum: NSNumber {
        let stringValue = self
        let range = stringValue.range(of: #"\d+(\.\d+)*\s+\w+"#,
                                        options: .regularExpression)
        guard range.location != NSNotFound else { return -1 }
        let numberExpression = stringValue.substring(with: range)

        let formatter = NumberFormatter()
        formatter.isLenient = true
        formatter.numberStyle = .spellOut
        return formatter.number(from: numberExpression) ?? -1
    }
}

如果我们遵循@rmaaddy的建议,返回一个可选的而不是“魔数” -1,则代码如下所示:

extension NSString { 
    public var asNum: NSNumber? {
        let stringValue = self
        let range = stringValue.range(of: #"\d+(\.\d+)*\s+\w+"#,
                                        options: .regularExpression)
        guard range.location != NSNotFound else { return nil }
        let numberExpression = stringValue.substring(with: range)

        let formatter = NumberFormatter()
        formatter.isLenient = true
        formatter.numberStyle = .spellOut
        return formatter.number(from: numberExpression) ?? nil
    }
}