Используйте * как обычный объект фильтрации символов с «НРАВИТСЯ» в Realm

Я пытаюсь найти строку, содержащую подстроку с подстановочным знаком. В следующем примере строка должна подтверждать шаблон (любые символы '*' любые символы 'p' любые символы) . Я пробую этот код для поиска объектов из Realm

class ServiceMessage: Object {
  @objc dynamic var desc = ""
}

let realm = try! Realm()

let dataSource = [
    "Domain CheckService",
    "IMEI check",
    "Compliant about service provider",
    "Compliant about TRA",
    "Enquires",
    "Suggestion",
    "SMS* S[pam",
    "Poor Coverage",
    "Pure *Signal",
    "Help Salim"
]

for text in dataSource {
    let sm = ServiceMessage()
    sm.desc = text;
    try! realm.write {
        realm.add(sm)
    }
}


let searchString = "*\\**p*"
let predicate = NSPredicate(format: "SELF.desc LIKE[c] %@", searchString)
let errors = realm.objects(ServiceMessage.self).filter(predicate)

Я ничего не получил. Если я попытаюсь отфильтровать простой массив строк с помощью этого предиката, все будет работать нормально. Кто-нибудь знает решения этой проблемы? Я пытаюсь добавить [w] после LIKE, это мне не помогает.


person Ivan Titkov    schedule 06.02.2018    source источник
comment
Вам помог мой ответ???   -  person Reinier Melian    schedule 06.02.2018
comment
привет, спасибо за ответ, но нет. 1. Как видите, я упомянул, что могу фильтровать массив с помощью предиката, в то же время для меня ваш шаблон сложнее, чем я использую. Также я не хочу использовать регулярное выражение. Насколько я понимаю, я использовал зарезервированный подстановочный знак, поэтому я просто хочу использовать этот символ как символ, а не как зарезервированный символ.   -  person Ivan Titkov    schedule 06.02.2018
comment
хорошо, удачи с этим, когда вы найдете ответ на этот вопрос, отправьте его   -  person Reinier Melian    schedule 06.02.2018
comment
@ReinierMelian ценю вашу помощь, удачи!   -  person Ivan Titkov    schedule 06.02.2018


Ответы (1)


Основная проблема здесь в том, что вы не можете использовать регулярное выражение в качестве предикатов в Realm, как мы можем прочитать здесь https://github.com/realm/realm-cocoa/issues/2629 правильный способ сделать это должен быть

let realmInstance = try? Realm()
let expresion = ".*\\*.*p.*"
let predicate = NSPredicate(format: "SELF.name MATCHES %@", expresion)
self.realmArrayDogs = realmInstance?.objects(Dog.self).filter(predicate)

но это приведет к сбою со следующей ошибкой

Завершение работы приложения из-за необработанного исключения «Недопустимый тип оператора», причина: «Оператор MATCHES не поддерживается для строкового типа»

это пример такой же работы со строковым массивом

let array = ["D*usadpdasd","probando","asdasd*ffffpppp"]
    do{
        let expresion = ".*\\*.*p.*"
        let predicate = NSPredicate(format: "SELF MATCHES %@",expresion)
        let resultArray = array.filter({predicate.evaluate(with: $0)})
        debugPrint(resultArray)
    }
    catch
    {

    }

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

Это работает!

let realmInstance = try? Realm()
let expresion = ".*\\*.*p.*"
let predicate = NSPredicate(format: "SELF.name MATCHES %@", expresion)
let arrayOfDogsResult = realmInstance?.objects(Dog.self)
let filteredArray = Array(arrayOfDogsResult!).filter({predicate.evaluate(with: $0)})
debugPrint(filteredArray)
person Reinier Melian    schedule 06.02.2018