2010-08-28 16 views
30

Szukam rozwiązania, jak sformatować NSPredicate, aby wyszukać poprawne słowo w ciągu tekstowym. Obecnie używam tego kodu:Jak znaleźć rozpoczynające się słowo w ciągu używając NSPredicate?

NSPredicate *predicate = [NSPredicate predicateWithFormat: 
          @"(content CONTAINS[c] %@)", word]; 

ale zwraca błędne resuls jeśli słowo jest krótkie, na przykład: jeśli słowo jest „ail” zwróci wszystkie ciągi ze słowami, które zawierają to 3 litery. Ale nie potrzebuję takiego abstrakcyjnego wyszukiwania, więc jak wyszukiwać słowa "zaczyna" od "moje słowo w ciągu znaków"?

Odpowiedz

56

Po prostu użyj BEGINSWITH zamiast CONTAINS.

Edit

Jeśli trzeba szukać w każdym słowie ciąg, nie jest techniką, która została przedstawiona w jednej z rozmów w WWDC 2010. Podstawowym założeniem jest stworzenie oddzielnej jednostki Word który zawiera pojedyncze słowo i odniesienie do obiektu zawierającego (wyszukiwanego obiektu). Następnie wyszukujesz encję w jednostce Word i zwracasz obiekty związane z znalezionymi słowami.

Kwerenda będzie wtedy wyglądać tak (pod warunkiem, że masz wiele do jednego relacji między jednostką a Word: „żadnych słów BEGINSWITH [c]% @”

Oznaczałoby to, że trzeba konfiguracja słowa podczas tworzenia obiektów chociaż.

+0

Dziękuję za poświęcony czas, ale ja mówię o sznurku, ani słowa. Jeśli użyję beginwith, zwróci on wszystkie ciągi zaczynające się od mojego słowa, ale muszę zwrócić ciągi zawierające słowa, zaczyna się od mojego słowa ... – azia

+0

Potrzebne jest coś w stylu "dowolne słowo w treści zaczyna się od XX" ? – Alfonso

+0

Tak, coś takiego. Ale powinien zwrócić cały ciąg. Chodzi o to, że muszę znaleźć w nowych recepturach Core Data z jednym ze składników według tytułu receptury. Na przykład, gdy szukam jabłka, muszę znaleźć przepisy o tytule "Fuji Apples Tarte Tatin". – azia

18

najpierw BEGINSWITH dla „Foo” szukaj to znajdziesz początki ciąg

"Foo Word1 Word2", "Foo OtherWord1 OtherWord2" (will find 2) 

i niż CONTAINS dla „Foo” (nie e przestrzeń przed Foo), co daje słowa, które zaczyna się od „foo” przewodniczył o powierzchni

"Word1 Foo Word", "Some OtherWord FooWord", "Misc FooXWord" (will find 3) 

Predicate:

NSPredicate *predicate = [NSPredicate predicateWithFormat: 
          @"(content BEGINSWITH[c] %@) OR (content CONTAINS[c] %@)", word, [NSString stringWithFormat:@" %@", word]]; 
+1

To właśnie chcę .. zmieniać inteligentną odpowiedź ... Dzięki, koleś – guru

6

Jeżeli tekst zawiera pewne znaki interpunkcyjne pomiędzy słowami można używać ten predykat:

NSPredicate *predicate = [NSPredicate predicateWithFormat: 
           @"(name BEGINSWITH[c] %@) OR (name MATCHES[c] %@)", 
           query, 
           [NSString stringWithFormat:@".*[^\\w]%@.*", query]]; 
+0

Wow! Myślałem, że tokenizacja była jedynym rozwiązaniem, dopóki tego nie zobaczyłem. – 8suhas

+1

Mam zaktualizowane rozwiązanie. Teraz nie jest wymagana interpunkcja. –

7

Miałem ten sam problem i na początku myślałem, że twoje odpowiedzi mogą mi pomóc, ale nie zrobiły tego. Ten pomógł mi, więc ... Spójrz:

NSString *matchString = [NSString stringWithFormat: @".*\\b%@.*",searchText]; 
NSString *predicateString = @"keyword MATCHES[c] %@"; 
NSPredicate *predicate =[NSPredicate predicateWithFormat: predicateString, matchString]; 
0

Spróbuj użyć związek:

NSCompoundPredicate *bPredicate =  [NSCompoundPredicate orPredicateWithSubpredicates:@[[NSPredicate predicateWithFormat:@"content BEGINSWITH[cd] %@",_SearchBar.text], [NSPredicate predicateWithFormat:@"content CONTAINS[cd] %@", _SearchBar.text]]]; 
Powiązane problemy