【问题标题】:Swift: substring (integer/number) from a stringSwift:字符串中的子字符串(整数/数字)
【发布时间】:2018-10-13 23:12:45
【问题描述】:

我正在我的应用程序中开发语音识别器模块。语音识别器返回一个字符串(可能有一段时间带有垃圾字符串信息,与用户的语音密切匹配),我必须评估字符串中的特定命令。

这是我得到的一些语音结果字符串示例:

  • “开箱”
  • “开箱 1234”
  • “打开案例 id 3421”
  • “开箱号 9546”
  • “打开案例编号 5241”
  • “开箱9552开箱”
  • “开箱开箱 6842”
  • “开箱 bla bla 5415 bla”
  • “开箱 1234 bla bla”
  • “开箱号 54675 bla bla 1234 bla”。 // 第一个整数应该在命令中考虑

现在,我有一组命令列表,其中一个命令是open case <Integer value>

我可以使用 Swift 的子字符串实用函数轻松评估单词 open case。但问题是,我必须从关键字open case 之后的语音字符串中找出(识别并获取)一个整数。

我查看了以下答案,但找不到确切的结果/解决方案:

【问题讨论】:

  • 正则表达式模式"open case [0-9]+"怎么样?

标签: swift string int substring


【解决方案1】:

我推荐正则表达式。

模式搜索

  • 字面意思“开箱”,
  • 可选的空白字符 (\\s?)
  • 一位或多位数字。 (\\d+) 被捕获

代码评估所有示例:

let array = ["open case", "open case 1234", "open case id 3421", "open case no 9546", "open case number 5241", "open case 9552 open case", "open case open case 6842", "open case bla bla 5415 bla", "open case 1234 bla bla", "open case number 54675 bla bla bla"]

func evaluate(string : String) -> String? {
    let pattern = "open case\\s?(\\d+)"
    let regex = try! NSRegularExpression(pattern: pattern) // as the pattern is hard-coded try! is safe
    if let match = regex.firstMatch(in: string, range: NSRange(string.startIndex..., in: string)) {
        let range = Range(match.range(at: 1), in: string)!
        return String(string[range])
    }
    return nil
}

let found = array.compactMap { evaluate(string: $0) } // ["1234", "9552", "6842", "1234"]

如果您想考虑(实际上忽略)open case 和整数之间的所有内容,请使用模式

"open case\\D+(\\d+)"

\\D+ 代表一个或多个非数字字符。

【讨论】:

  • 需要你再帮忙找出一个准确的正则表达式模式,匹配这个字符串open bla case bla 62 72 769 bla bla。我已经尝试过这个open\\D+case\\D+(\\d+)\\s*(\\d+)\\s*(\\d+),但如果space + number 的组合有超过3 个匹配项,它就会失败。
  • 试试"open\\D+case\\D+([\\d ]+\\d)",数字搜索会考虑带尾随数字的数字和空格。
  • 谢谢你..你太棒了!我怎么没想到呢?
  • 如果您还想只考虑一个数字,则必须将右括号(一个或多个)后的 + 替换为 *(零个或多个)
【解决方案2】:

我喜欢正则表达式。

let input = "open case 1234 bla bla"
let pattern = "open case ([0-9]+)"
do {
    let regex = try NSRegularExpression(pattern: pattern, options: .caseInsensitive)
    let matches = regex.matches(in: input, options: [], range: NSRange(location: 0, length: input.utf16.count))
    if matches.count > 0 {
        let match = matches[0]
        let r = match.range(at: 1)
        let num = input.substring(with: Range(r, in: input)!)
        // "1234"
    }
} catch {
    print("illegal regex")
}

【讨论】:

  • 我正在向您展示一种可能的技术,而不是为您编写代码。
【解决方案3】:

你可以使用类似的东西:

let string = "open case 9552 open case"

if let number = string.components(separatedBy: .whitespaces).compactMap(Int.init).first {
    print(number)
}

如果您使用的是 Swift 4.0 或更低版本,请使用 flatMap 而不是 compactMap

【讨论】:

    猜你喜欢
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 2015-09-11
    • 1970-01-01
    • 1970-01-01
    • 2015-04-02
    • 1970-01-01
    • 2015-10-22
    相关资源
    最近更新 更多