Swift: подстрока (целое число / число) из строки - PullRequest
0 голосов
/ 03 мая 2018

Я работаю над модулем распознавания речи в моем приложении. Распознаватель речи возвращает строку (может быть, когда-нибудь с информацией о строке мусора, близко совпадающей с речью пользователя), и я должен оценить конкретную команду из строки.

Вот несколько примеров строк с речевым результатом, которые я получаю:

  • «открытый ящик»
  • "открытый корпус 1234"
  • "open case id 3421"
  • "открытый ящик № 9546"
  • "открытый ящик № 5241"
  • «открытый кейс 9552 открытый кейс»
  • "открытый корпус 6842"
  • «открытый корпус бла бла 5415 бла»
  • «открытый корпус 1234 бла бла»
  • «открытый ящик № 54675 бла бла 1234 бла». // первое целое число должно учитываться в команде

Теперь у меня есть список команд, одна из команд open case <Integer value>

Я мог легко оценить слово open case, используя вспомогательные функции подстроки Swift. Но проблема в том, что я должен узнать (идентифицировать и получить) целое число из речевой строки после ключевого слова open case.

Я искал следующий ответ, но не смог найти точный результат / решение:

Ответы [ 3 ]

0 голосов
/ 03 мая 2018

Мне нравится регулярное выражение.

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")
}
0 голосов
/ 03 мая 2018

Я рекомендую регулярное выражение.

Шаблон ищет

  • Буквально "open case",
  • Необязательный символ пробела (\\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+ представляет один или несколько нецифровых символов.

0 голосов
/ 03 мая 2018

Вы можете использовать что-то вроде:

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...