Wykrywanie, czy NSString zawiera…?

124

Jak mogę wykryć, czy ciąg zawiera określone słowo? Na przykład mam poniżej ciąg, który brzmi:

@"Here is my string."

Chciałbym wiedzieć, czy potrafię wykryć słowo w ciągu, na przykład „jest”.

Alex
źródło
możliwy duplikat Searching NSString Cocoa?
kennytm
26
czy możesz przyjąć odpowiedź?
Jacob Relkin
Tanim i brudnym rozwiązaniem, jeśli zakłada się, że ciąg nie zawiera znaków interpunkcyjnych, jest łączenie spacji z przodu iz tyłu OBU łańcuchów, a następnie zrób to rangeOfString.
Hot Licks

Odpowiedzi:

192

Oto jak bym to zrobił:

NSString *someString = @"Here is my string";
NSRange isRange = [someString rangeOfString:@"is " options:NSCaseInsensitiveSearch];
if(isRange.location == 0) {
   //found it...
} else {
   NSRange isSpacedRange = [someString rangeOfString:@" is " options:NSCaseInsensitiveSearch];
   if(isSpacedRange.location != NSNotFound) {
      //found it...
   }
}

Możesz łatwo dodać to jako kategorię do NSString:

@interface NSString (JRStringAdditions) 

- (BOOL)containsString:(NSString *)string;
- (BOOL)containsString:(NSString *)string
               options:(NSStringCompareOptions)options;

@end

@implementation NSString (JRStringAdditions) 

- (BOOL)containsString:(NSString *)string
               options:(NSStringCompareOptions)options {
   NSRange rng = [self rangeOfString:string options:options];
   return rng.location != NSNotFound;
}

- (BOOL)containsString:(NSString *)string {
   return [self containsString:string options:0];
}

@end
Jacob Relkin
źródło
2
Właściwie możesz po prostu dodać spację na początku i na końcu ciągu, a „is” dopasuje ciąg zaczynający się od „is”
user4951
Zdumiewa mnie, że nie należą one do klas standardowych. Dzięki, @Jacob!
big_m
1
Właściwie to "długość" NSRange powinna być testowana ... a nie "lokalizacja". Tutaj jest bezpośrednio ze źródła: "Te metody zwracają length == 0, jeśli nie znaleziono ciągu docelowego. Aby więc sprawdzić, czy nie ma zawartości: ([ str rangeOfString: @ "target"]. length> 0). Należy pamiętać, że długość zakresu zwracanego przez te metody może być inna niż długość ciągu docelowego, ze względu na złożone znaki i tym podobne. "
GtotheB
Począwszy od iOS 8.0, containsStringw NSString dostępna jest nowa metoda o nazwie ujawniona.
tedyyu
89

Użyj poniższego kodu, aby zeskanować słowo w zdaniu.

NSString *sentence = @"The quick brown fox";
NSString *word = @"quack";
if ([sentence rangeOfString:word].location != NSNotFound) {
    NSLog(@"Yes it does contain that word");
}
Amit Singh
źródło
jak mogę uzyskać lokalizacje, gdy używam tej metody na tablicy?
sędzia
Zależy od tego, czego szukasz w tablicy. Myślę, że bez użycia komparatorów najlepszym sposobem jest zapętlenie tablicy i sprawdzenie każdego ciągu pod kątem szukanego ciągu. NSString * searchString; for (NSString * string in array) {if ([string rangeOfString: searchString options: NSCaseInsensitiveSearch] .location! = NSNotFound) {// Not in string} else {// In this string}} Możesz następnie dodać ciągi, które
zawrzeć
ps Formatowanie jest poprawne w powyższym kodzie, ale oczywiście zostaje zmiażdżone przez umieszczenie w komentarzu
simon_smiley
22

W iOS8 możesz teraz używać:

BOOL containsString = [@"Here is my string." containsString:@"is"];

Jest tam interesujący post o tym, jak „doposażyć” go do iOS7: http://petersteinberger.com/blog/2014/retrofitting-containsstring-on-ios-7/

siburb
źródło
Byłaby to bardzo miła, poręczna metoda. Niestety nie jest to udokumentowane i dlatego jest to prywatne API
Centurion
2
Na pewno nie jest to prywatny interfejs API. Sprawdź plik NSString.h, a zobaczysz go.
Brian Sachetta
3

Polecam używanie NSLinguisticTagger . Możemy go użyć do wyszukiwaniaHere is my string. His isn't a mississippi isthmus. It is?

NSLinguisticTagger *linguisticTagger = [[NSLinguisticTagger alloc] initWithTagSchemes:@[
                                        NSLinguisticTagSchemeTokenType,
                                        ]
                                                                              options:
                                        NSLinguisticTaggerOmitPunctuation |
                                        NSLinguisticTaggerOmitWhitespace |
                                        NSLinguisticTaggerOmitOther ];
[linguisticTagger setString:@"Here is my string. His isn't a mississippi isthmus. It is?"];
[linguisticTagger enumerateTagsInRange:NSMakeRange(0,
                                                   [[linguisticTagger string] length])
                                scheme:NSLinguisticTagSchemeTokenType
                               options:
 NSLinguisticTaggerOmitPunctuation |
 NSLinguisticTaggerOmitWhitespace |
 NSLinguisticTaggerOmitOther |
 NSLinguisticTaggerJoinNames
                            usingBlock:^(NSString *tag, NSRange tokenRange, NSRange sentenceRange, BOOL *stop) {
                                NSLog(@"tag: %@, tokenRange: %@, sentenceRange: %@, token: %@",
                                      tag,
                                      NSStringFromRange(tokenRange),
                                      NSStringFromRange(sentenceRange),
                                      [[linguisticTagger string] substringWithRange:tokenRange]);
                            }];

To daje:

tag: Word, tokenRange: {0, 4}, sentenceRange: {0, 19}, token: Here
tag: Word, tokenRange: {5, 2}, sentenceRange: {0, 19}, token: is
tag: Word, tokenRange: {8, 2}, sentenceRange: {0, 19}, token: my
tag: Word, tokenRange: {11, 6}, sentenceRange: {0, 19}, token: string
tag: Word, tokenRange: {19, 3}, sentenceRange: {19, 33}, token: His
tag: Word, tokenRange: {23, 2}, sentenceRange: {19, 33}, token: is
tag: Word, tokenRange: {25, 3}, sentenceRange: {19, 33}, token: n't
tag: Word, tokenRange: {29, 1}, sentenceRange: {19, 33}, token: a
tag: Word, tokenRange: {31, 11}, sentenceRange: {19, 33}, token: mississippi
tag: Word, tokenRange: {43, 7}, sentenceRange: {19, 33}, token: isthmus
tag: Word, tokenRange: {52, 2}, sentenceRange: {52, 6}, token: It
tag: Word, tokenRange: {55, 2}, sentenceRange: {52, 6}, token: is

Ignoruje, His mississippia isthmusnawet identyfikuje iswnętrze isn't.

Heath Borders
źródło
3

Mam nadzieję, że to ci pomoże ... dodaj tę linię w pliku .m lub utwórz osobną klasę i zintegruj ten kod.

@implementation NSString (Contains)

- (BOOL) containsString: (NSString*) substring
{
NSRange range = [self rangeOfString : substring];
BOOL found = ( range.location != NSNotFound );
return found;
}    
@end
Maniganda saravanan
źródło
2

W iOS 8 i Swift możemy użyć metody localizedCaseInsensitiveContainsString

 let string: NSString = "Café"
 let substring: NSString = "É"

 string.localizedCaseInsensitiveContainsString(substring) // true
Govind
źródło
0

Kompletne rozwiązanie najpierw skanuje w poszukiwaniu ciągu (bez dodanych spacji), a następnie sprawdza, czy bezpośrednio poprzedzający znak jest pusty lub początek wiersza. Podobnie sprawdź, czy następujący po nim znak jest pusty lub koniec wiersza. Jeśli oba testy przejdą pomyślnie, masz zgodność. W zależności od potrzeb można również sprawdzić ,, ., (), itd.

Alternatywnym podejściem jest oczywiście przeanalizowanie ciągu na słowa i sprawdzenie każdego słowa indywidualnie.

Hot Licks
źródło