Текст диктовки (распознавание речи) не соответствует строке в Swift

avatar
Yousif Ismat
8 августа 2021 в 21:03
354
3
0

Я разработал функцию распознавания речи, которая может обнаруживать арабский звук и возвращать строку, которую я назначаю переменной с именем speechRecogText.

В коде у меня также есть текстовое поле, в котором я сохраняю ввод в другой строковой переменной с именем textFieldText.

Goal Я хочу проверить, содержит ли speechRecogText запросы в textFieldText<7230687689>, но это не работает с арабским языком .

Однако, когда я пытаюсь сделать наоборот speechRecogText.contains(textFieldText), все работает. Код ниже

    // the two variables
    var speechRecogText: String = ""
    var textFieldText: String = ""

Функции распознавания речи и текстовое поле... После ввода входных данных я вызываю функцию compareTexts()

func compareTexts() {
    
    // Checking the textField text
    if speechRecogText.contains(textFieldText) {
        print("matching texts")
    } else {
        print("not matching")
    }
    
    // Checking the speech recog text
    if textFieldText.contains(speechRecogText) {
        print("matching texts")
    } else {
        print("not matching")
    }
}

Например, оба напечатают слово "قل" на арабском языке. Но когда я вызываю функцию, консоль показывает (ответ):

Console 
//matching texts
//not matching

Я хочу, чтобы второй тоже работал/сопоставлялся и печатал совпадающие тексты.

Хотя обе переменные содержат одинаковый текст, результат немного сбивает с толку. Разве они не хранят одинаковые значения или отображают одну и ту же строку, но в глубине кода они как-то различаются?

Я был бы очень признателен за вашу поддержку :)

Вот весь код

Это весь код.

import SwiftUI
import SwiftSpeech

struct ContentView: View {
    
    @State var speechRecogText = "قل"
    @State var textFieldText = "قل"
    
    var body: some View {
        
        VStack {
            
            //MARK: - Text Field
                        
            TextField("textfield text", text: $textFieldText)
                .padding()
            
            Button(action: {
                compareTexts()
            } ) {
                ZStack {
                    Color.blue.clipShape(Circle()).frame(width: 70, height: 70)
                    Text("Check").foregroundColor(.white)
                }
            }
            
            
            //MARK: - Speech Recognition
            
            
            Text("speechRecogText: " + speechRecogText)
            
            SwiftSpeech.RecordButton()
                .swiftSpeechRecordOnHold(locale: Locale(identifier: "ar"),
                                         animation: .spring(),
                                         distanceToCancel: 50)

                .onRecognizeLatest { result in
                    self.speechRecogText = result.bestTranscription.formattedString
                    if result.isFinal {
                        print("last transcript")
                    }
                } handleError: { error in
                    print("Failed recognizing the audio. Retry: \(error)")
                }
        }
        
    }
    

    func compareTexts() {
        // Checking the textField text
        if speechRecogText.contains(textFieldText) {
            print("---> speechRecogText contains textFieldText")
        } else {
            print("---> speechRecogText DOES NOT contains textFieldText")
        }

        // Checking the speech recog text
        if textFieldText.contains(speechRecogText) {
            print("---> textFieldText contains speechRecogText")
        } else {
            print("---> textFieldText DOES NOT contains speechRecogText")
        }
    }
}
Источник
workingdog support Ukraine
8 августа 2021 в 23:13
0

Не могли бы вы привести еще несколько примеров арабского текста, где он не работает, потому что мой тест с использованием вашего примера арабского текста работает для меня.

Yousif Ismat
9 августа 2021 в 12:08
0

Я попробовал кучу других слов. Они не работали. Можете ли вы попробовать просто случайные слова или короткие фразы?

Yousif Ismat
9 августа 2021 в 12:14
0

Если вы считаете, что будет лучше поделиться функциями распознавания речи, я

workingdog support Ukraine
9 августа 2021 в 12:40
0

нет необходимости в голосовой функции, просто дайте мне текст, который не работает. Весь текст, который я помещаю в свои тесты, работает.

Yousif Ismat
9 августа 2021 в 17:25
0

И вы используете тот же код? Можете ли вы поделиться кодом? Потому что, честно говоря, я пробовал разные слова, и ни одно из них не соответствовало тому порядку, в котором я хочу.

Ответы (3)

avatar
Didier B.
23 января 2022 в 01:22
0

Универсальное решение для любого языка

Я заметил, что диктовка фактически добавляет к обрабатываемой строке нулевой символ, чей unicodeScalar равен 65532 или \u{fffc}, что делает строку непригодной для поиска. В арабском языке он может стать первым символом из-за направления строки.

extension String {
    func removeNilCharacters() -> String {
        return self.replacingOccurrences(of: "\u{fffc}", with: "", options: String.CompareOptions.literal, range: nil)
    }
}

Применение .removeNilCharacters() к строке, возвращаемой текстовым полем, должно решить проблему, независимо от того, была вызвана диктовка или нет.

avatar
Yousif Ismat
10 августа 2021 в 23:55
0

Итак, после тестирования кода я понял, что текст распознавания речи содержит больше символов, чем жестко заданная строка. Когда я использовал .count() для текста textField «قل», он напечатал 2, но для распознавания речи он напечатал 3.

Я использовал метод сопоставления для просмотра дополнительного символа.

speechRecogText.map({ print($0) })

Похоже, первый символ был пустым местом. Поэтому я использовал

speechRecogText.removeFirst()

а затем сравнили. И результат был таким, каким хотелось.

workingdog support Ukraine
11 августа 2021 в 00:18
0

отлично, если бы вы использовали мой .trim() и код в моем ответе, это давно бы сработало.

Yousif Ismat
11 августа 2021 в 00:29
0

Я использовал, но по какой-то причине это не сработало. Может быть, что-то было не так, когда я пробовал ваш. Но большое спасибо за вклад и усилия :)

workingdog support Ukraine
11 августа 2021 в 00:31
0

спасибо, что сообщили. Можете ли вы использовать функцию обрезки и дайте мне знать, если это работает сейчас.

Yousif Ismat
11 августа 2021 в 15:42
0

Я снова проверил это с помощью .count(), .map() и .contain(). Но по какой-то причине .trim() не удалял пустые места. Даже если это два слова в строке.

Yousif Ismat
11 августа 2021 в 15:42
0

Однако я благодарен. .removeFirst() сработало!

avatar
workingdog support Ukraine
9 августа 2021 в 12:39
0

хорошо, вот как я тестировал сравнение арабских текстов. Он показывает ожидаемые результаты.

 import SwiftUI

@main
struct TestApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

struct ContentView: View {
    @State var results1 = "testing1"
    @State var results2 = "testing2"
    var speechRecogText: String = "قلّ"
    var textFieldText: String = "قلّ جسمه من الكبَر"
    
    func compareTexts() {
        // Checking the textField text
        if speechRecogText.trim().contains(textFieldText.trim()) {
            results1 = "speechRecogText contains textFieldText"
            print("---> speechRecogText contains textFieldText")
        } else {
            results1 = "speechRecogText DOES NOT contains textFieldText"
            print("---> speechRecogText DOES NOT contains textFieldText")
        }
        // Checking the speech recog text
        if textFieldText.trim().contains(speechRecogText.trim()) {
            results2 = "textFieldText contains speechRecogText"
            print("---> textFieldText contains speechRecogText")
        } else {
            results2 = "textFieldText DOES NOT contains speechRecogText"
            print("---> textFieldText DOES NOT contains speechRecogText")
        }
    }
    
    var body: some View {
        VStack (spacing: 50) {
            Text(results1)
            Text(results2)
        }
        .onAppear {
            compareTexts()
        }
    }
}

extension String {
    func trim() -> String {
        return self.trimmingCharacters(in: .whitespacesAndNewlines)
    }
}
Yousif Ismat
9 августа 2021 в 17:19
0

Это не работает. Знаете ли вы, что speechRecogText взят из текста распознавания речи (например, диктовки)?

Yousif Ismat
9 августа 2021 в 17:21
0

Консоль печатает ---> speechRecogText содержит textFieldText ---> textFieldText НЕ содержит speechRecogText

workingdog support Ukraine
9 августа 2021 в 22:56
0

это не те результаты, которые я получаю. Я получаю правильные результаты: ---> speechRecogText НЕ содержит textFieldText и ---> textFieldText содержит speechRecogText. Можете ли вы рассказать нам, какие системы вы используете, какой Mac, ios, цель вы устанавливаете. Крайне маловероятно, что это не сработает на другом Mac или iOS.

workingdog support Ukraine
9 августа 2021 в 23:00
0

Не могли бы вы также попробовать заменить «содержит» на «localizedCaseInsensitiveContains», посмотрите, сработает ли это для вас.

Yousif Ismat
10 августа 2021 в 12:46
0

Это 13-дюймовый MacBook Pro 2019 года, целью разработки является новейшая версия 14,5, поскольку при тестировании функциональности в простом проекте. Для функции преобразования речи в текст я использую стороннюю библиотеку под названием SwiftSpeech для распознавания речи. Вот ссылка .

Yousif Ismat
10 августа 2021 в 12:48
0

Не могли бы вы поделиться со мной всем проектом, чтобы я мог протестировать его и посмотреть, с моего ли это устройства или...

workingdog support Ukraine
10 августа 2021 в 12:52
0

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

Yousif Ismat
10 августа 2021 в 12:58
0

В вашем примере вы жестко закодировали переменные, в моем примере я получаю речь и преобразовываю ее в текст, а затем присваиваю это значение моему speechRecogText.

Yousif Ismat
10 августа 2021 в 12:59
0

Ваш код работает нормально, но у него нет метода распознавания речи, который присваивает значение.

workingdog support Ukraine
10 августа 2021 в 13:13
0

Я вижу, у вас есть проблемы в другом месте вашего кода. Мой ответ показал вам, что сравнение арабского текста работает? Это то, что было вашей целью, верно? Вы говорите, что у вас есть проблема с помещением строки в строковую переменную. Покажите нам код, который вы используете для этого.

Yousif Ismat
10 августа 2021 в 13:16
0

Проверьте вопрос еще раз, я обновил и добавил весь код. Поскольку .trim() не работал, я просто удалил его. Вы можете думать об этом как об исходном коде.

workingdog support Ukraine
10 августа 2021 в 13:26
0

Не могли бы вы добавить в свою кнопку перед compareTexts() эту строку и показать мне результат: print("speechRecogText: \(speechRecogText) textFieldText: \(textFieldText)")

Yousif Ismat
10 августа 2021 в 13:54
0

Результат: speechRecogText: ‏قل textFieldText: قل

workingdog support Ukraine
10 августа 2021 в 14:07
0

и при этом вы говорите мне, что compareTexts() дает вам неправильные результаты? Пожалуйста, покажите, что печатает compareTexts(). Я копирую и вставляю текст в свой код, и он отлично работает.

Yousif Ismat
10 августа 2021 в 14:10
0

Полный результат: speechRecogText: ‏قل textFieldText: قل ---> speechRecogText содержит textFieldText ---> textFieldText НЕ содержит speechRecogText

Yousif Ismat
10 августа 2021 в 14:11
0

Эта проблема является критической, но очень странной. Можете ли вы просто поделиться со мной файлом проекта, и я запущу ваш проект, чтобы увидеть результаты?

workingdog support Ukraine
10 августа 2021 в 14:18
0

мой файл проекта - это код в моем ответе, не более того. Я копирую и вставляю текст, который вы мне дали, и он отлично работает. Можете ли вы поместить функцию trim(), как в моем коде, чтобы обрезать все пробелы в тексте. Это текст, который я вставил: var speechRecogText: String = "قل" var textFieldText: String = "قل"

Yousif Ismat
10 августа 2021 в 14:59
0

Вы тоже используете стороннюю библиотеку?

workingdog support Ukraine
10 августа 2021 в 15:02
0

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

Yousif Ismat
10 августа 2021 в 23:20
0

Можете ли вы попробовать этот код. Сделайте два текстовых поля. Слово вводится с клавиатуры. другой использует диктовку и сравнивает эти два текста. Вы получите такие же результаты?

workingdog support Ukraine
10 августа 2021 в 23:53
0

Я подозреваю, что "speechRecogText" может обновляться, потому что вы не останавливаете запись. Чтобы проверить это, в своем "SwiftSpeech.RecordButton()" вы можете поместить это .swiftSpeechToggleRecordingOnTap(locale: Locale(identifier: "ar"), animation: .spring()) вместо "swiftSpeechRecordOnHold(...)" и убедиться, что запись остановлена ​​(нажмите кнопку записи еще раз), прежде чем нажимать "compareTexts ()" кнопка.

Yousif Ismat
10 августа 2021 в 23:56
0

Я понял. Проверьте, я дал ответ на свой вопрос :)