Анализируем речь и выполняем действие - PullRequest
1 голос
/ 09 июля 2020

Я пытаюсь проанализировать предложение и совершить действие в зависимости от этого. Вот примеры предложений, полученных при распознавании речи. Я написал пару предложений, потому что мы точно не знаем, что скажет пользователь, и правильно ли он говорит.

var str = "20 minutes to take a shower"
var sentence = "seven minutes to make 10 last homeworks"
var sentence2 = "strum guitar for 15 minutes"
var plans = "launch with friend 12:15, then drawing lesson"

Я хочу извлечь «20 минут»; назначьте его для timeValue и запустите таймер. Кроме того, чтобы назначить задачу taskValue, чтобы представить задачу, которую я выполняю. (Я думал получить значение задачи, удалив «20 минут» из начального предложения).

  1. Как вы думаете, как лучше всего работать со строкой, которую мне нужно проанализировать? Я думал найти диапазоны индексов, а затем вырезать / копировать с помощью индексов, но

Формат возвращаемых индексов такой: и я не знаю, как извлечь количество индекс. (В данном случае: от 0 до 10)

{0, 10} { [0-9] {1,} минут 0x1}

Как зажечь таймер? Мы должны убедиться, что дана правильная команда. И когда мы получим timeValue и taskValue обратно, как тогда нам запустить таймер? (Весь процесс был следующим: пользователь нажимает кнопку -> пользователь говорит -> распознается речь (и отображается на метке экрана) -> предложение анализируется (?) -> запускается таймер (?) И задача отображается в метке (?)) Каковы ваши рекомендации по архитектуре системы анализа речи. Может быть, вы знаете какие-нибудь статьи об этом c?

Вот лог c для обнаружения речи.

var timeValue: Int = Int()
var taskValue: String = ""

func stringDeduction(of inputText: String) -> (Int?, String?) {

    let pattern = "[0-9]{1,} minutes"
    let regexOptions: NSRegularExpression.Options = [.caseInsensitive]
    let matchingOptions: NSRegularExpression.MatchingOptions = [.reportCompletion]

    // TODO - catch errors with regex
    let regex = try! NSRegularExpression(pattern: pattern, options: regexOptions)
    //    } catch {
    //        print("error in regex")
    //    }
    let range = NSRange(location: 0, length: inputText.utf8.count)

    // \d - matches any digit
    // Pattern for time format like this 00:00
    //let patternForTime = "[0-9]{1,}:[0-9]{1,2}"




    if let matchIndex = regex.firstMatch(in: inputText, options: matchingOptions, range: range) {
    print(matchIndex)
    
    } else {
        print("No match.")
    }
    // check whether the string matches and print one of two messages


    if let match = regex.firstMatch(in: inputText, range: NSRange(location: 0, length: inputText.utf8.count)) {
        print("*: Match!")
    } else {
        print("*: No match.")
    }

    /* Question - how to use "mathces" properly?!
    if let match = regex.matches(in: testString, options: .reportCompletion ,range: NSRange(location: 0, length: testString.utf8.count)) {
        print("*: Match!")
        print(match)
    } else {
        print("*: No match.")
    }
    */


    func matches(for regex: String, in text: String) -> [String] {
    do {
        let regex = try NSRegularExpression(pattern: regex)
        let results = regex.matches(in: text, options: [], range:     NSRange(text.startIndex..., in: text))
        
            return results.map {
                String(text[Range($0.range, in: text)!])
            }
        
        } catch {
            print("invalid regex")
            return []
        }
    }

    var task = regex.stringByReplacingMatches(in: inputText, options: .withoutAnchoringBounds, range: range, withTemplate: "")
    //var taskMutableString = NSMutableString(string: str)
    //regex.replaceMatches(in: taskMutableString, options: .withoutAnchoringBounds, range:     range, withTemplate: "")
    //taskMutableString

    var timeStringArray = matches(for: pattern, in: inputText)
    var timeString = timeStringArray[0]
    let time = Int(timeString.replacingOccurrences(of: " minutes", with: ""))
    timeValue = time ?? Int()


    taskValue = task.replacingOccurrences(of: "to" , with: "", options: .caseInsensitive, range: task.startIndex..<task.index(task.startIndex, offsetBy: 4))
    let taskReturn = taskValue

    return (time, taskReturn)
 
    // the regex ^[ \t]+|[ \t]+$ matches excess whitespace at the beginning or end of a line.
    // what regex, or string method matches exess whitespace at the beginning of a line
}

Вот расширение для работы со строкой, как с массив. Вот так: - str [0..2]

extension String {
    subscript (bounds: CountableClosedRange<Int>) -> String {
        let start = index(startIndex, offsetBy: bounds.lowerBound)
        let end = index(startIndex, offsetBy: bounds.upperBound)
        return String(self[start...end])
    }

    subscript (bounds: CountableRange<Int>) -> String {
        let start = index(startIndex, offsetBy: bounds.lowerBound)
        let end = index(startIndex, offsetBy: bounds.upperBound)
        return String(self[start..<end])
    }
}

Вот еще один подход, который я пробовал: (Хотя это не кажется хорошим)

let timeArray = ["one minute", "two minutes", "three minutes", "four minutes", "five minutes", "six minutes", "seven minutes", "eight minutes", "nine minutes"]
let timeValueCheck = "Answer: \(sentence.containsAny(of: timeArray) ?? "doesn't contain")"

//Dividing String into words
let abc: [String] = str.components(separatedBy: " ")

// Finding a number within an array of words
// There's a problem if there are couple of numbers in the sentence, it returns all of them and not only the needed time.

let numbers = abc.compactMap {
  // convert each substring into an Int
  return Int($0)
}

for i in 1...100 {
    if str.contains(String(i) + " minutes") {
        print(i)
    }
}

Спасибо за любой из ваша помощь! Я просто сошел с ума от этой задачи на 3 месяца. Также, если что-то непонятно или немного запутано, скажите, пожалуйста! Попробую поправить.

...