Wie überprüfe ich, ob eine Zeichenfolge eine andere Zeichenfolge in Objective-C enthält?

1212

Wie kann ich überprüfen, ob eine Zeichenfolge ( NSString) eine andere kleinere Zeichenfolge enthält?

Ich hatte auf so etwas gehofft wie:

NSString *string = @"hello bla bla";
NSLog(@"%d",[string containsSubstring:@"hello"]);

Aber das nächste, was ich finden konnte, war:

if ([string rangeOfString:@"hello"] == 0) {
    NSLog(@"sub string doesnt exist");
} 
else {
    NSLog(@"exists");
}

Ist das der beste Weg, um herauszufinden, ob eine Zeichenfolge eine andere Zeichenfolge enthält?

Jonathan.
quelle
1
Ich würde es gerne auch hinzugefügt sehen, aber in der Zwischenzeit ist es relativ einfach, es als Kategorie auf NSString hinzuzufügen.
Isaac
2
Bei Verwendung if ([string rangeOfString:@"hello"] == 0) {...}gibt es einen Typinkongruenzfehler für NSRange und int. if ([string rangeOfString:@"hello"].length == 0) {...}
Um dies
1
iOS 8 fügt enthältString
Steve Moser
2
Ich war von Anfang an ein iOS-Entwickler und besuche diesen Beitrag ständig, um ihn schnell zu kopieren und einzufügen. Ich kann mir diesen nicht merken. Meistbesuchter Stackoverflow-Beitrag in meiner Geschichte.
VaporwareWolf
benutze einfach Swift;)
Fattie

Antworten:

2436
NSString *string = @"hello bla bla";
if ([string rangeOfString:@"bla"].location == NSNotFound) {
  NSLog(@"string does not contain bla");
} else {
  NSLog(@"string contains bla!");
}

Der Schlüssel bemerkt, dass rangeOfString:eine NSRangeStruktur zurückgegeben wird, und die Dokumentation besagt, dass die Struktur zurückgegeben wird, {NSNotFound, 0}wenn der "Heuhaufen" die "Nadel" nicht enthält.


Wenn Sie mit iOS 8 oder OS X Yosemite arbeiten, können Sie jetzt Folgendes tun: (* HINWEIS: Dies wird Ihre App zum Absturz bringen, wenn dieser Code auf einem iOS7-Gerät aufgerufen wird.)

NSString *string = @"hello bla blah";
if ([string containsString:@"bla"]) {
  NSLog(@"string contains bla!");
} else {
  NSLog(@"string does not contain bla");
}

(So ​​würde es auch in Swift funktionieren)

👍

Dave DeLong
quelle
286
Verwenden Sie "if ([Zeichenfolge rangeOfString: @" bla "-Optionen: NSCaseInsensitiveSearch] .location! = NSNotFound)"
Vanja
1
@ Dave DeLong Ich wollte gerade eine Kategorie erwähnen, die ich zu diesem Zweck erstellt habe, bevor ich Ihre Bearbeitung zur Antwort gelesen habe! Da ich hauptsächlich AC # -Entwickler bin, bin ich froh, dass sie NSSTring eine Include-Methode hinzugefügt haben.
dherrin79
Warum sagt der Compiler nichts, wenn mein Bereitstellungsziel iOS7 ist und ich includesString verwende?
Ricardo
3
Und um den Punkt von @Vanja weiter zu verfolgen: Wenn Sie den in iOS 8 / Yosemite eingeführten Verknüpfungscode [string includesString] verwenden möchten, können Sie den folgenden Code für eine Zeichenfolge verwenden, bei der die Groß- und Kleinschreibung nicht berücksichtigt wird: "[stringToSearch localizedCaseInsensitiveContainsString: Zeichenfolge ] ", und diese, wenn Sie eine Suche ohne Groß- und Kleinschreibung und ohne diakritische Empfindlichkeit durchführen möchten:" [stringToSearch localizedStandardContainsString: string] ".
Scott Kohlert
1
Beachten Sie, dass der Ausdruck [string rangeOfString:@"bla"].location != NSNotFoundsein wird wahr , wenn String nil!
Funroll
158

Für iOS 8.0+ und macOS 10.10+ können Sie NSStrings native verwenden containsString:.

Für ältere Versionen von iOS und macOS können Sie eine eigene (veraltete) Kategorie für NSString erstellen:

@interface NSString ( SubstringSearch )
    - (BOOL)containsString:(NSString *)substring;
@end

// - - - - 

@implementation NSString ( SubstringSearch )

- (BOOL)containsString:(NSString *)substring
{    
    NSRange range = [self rangeOfString : substring];
    BOOL found = ( range.location != NSNotFound );
    return found;
}

@end

Hinweis: Beachten Sie den Kommentar von Daniel Galasko zur Benennung

P i
quelle
13
+1 für klareren resultierenden Code und Wiederverwendbarkeit. Ich habe daraus einen return [self rangeOfString:substring].location != NSNotFound;Einzeiler gemacht und ihn in meine Refactoring-Bibliothek es_ios_utils aufgenommen. github.com/peterdeweese/es_ios_utils
Peter DeWeese
4
Es sieht so aus, als würde Apple Ihre Idee mögen und diese Funktion in iOS 8 und OSx 10.10 (Yosemite) hinzufügen, wie in seiner Antwort @DaveDeLong erwähnt. +1
Islam Q.
7
Die Grundregel für obj-c-Kategorien besteht darin, dem Methodennamen Ihr 3-Buchstaben-Modulpräfix voranzustellen. Dies ist das perfekte Beispiel, da es jetzt mit der Veröffentlichung von iOS 7 und 10.10 in Konflikt steht
Daniel Galasko
54

Da dies bei Google ein hochrangiges Ergebnis zu sein scheint, möchte ich Folgendes hinzufügen:

iOS 8 und OS X 10.10 fügen die containsString:Methode hinzu NSString. Eine aktualisierte Version von Dave DeLongs Beispiel für diese Systeme:

NSString *string = @"hello bla bla";
if ([string containsString:@"bla"]) {
    NSLog(@"string contains bla!");
} else {
    NSLog(@"string does not contain bla");
}
Lukas
quelle
39
NSString *myString = @"hello bla bla";
NSRange rangeValue = [myString rangeOfString:@"hello" options:NSCaseInsensitiveSearch];

if (rangeValue.length > 0)
{
    NSLog(@"string contains hello");
} 
else 
{
    NSLog(@"string does not contain hello!");
}

// Alternativ können Sie auch Folgendes verwenden:

if (rangeValue.location == NSNotFound) 
{
    NSLog(@"string does not contain hello");
} 
else 
{
    NSLog(@"string contains hello!");
}
AJS
quelle
22

Mit iOS 8 und Swift können wir die localizedCaseInsensitiveContainsString Methode verwenden

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

 string.localizedCaseInsensitiveContainsString(substring) // true
Govind
quelle
1
Das ist gut. Keine Ahnung, warum sie diese Methode nicht für iOS 7 hatten
Lucas
@ Lucas, weil Swift mit iOS 8.0 gestartet wurde. Aber mit Swift können Sie die Geräte immer noch mit iOS 7 unterstützen.
Hemang
13

Ich persönlich hasse NSNotFoundes wirklich, aber ich verstehe seine Notwendigkeit.

Einige Leute verstehen jedoch möglicherweise nicht die Komplexität des Vergleichs mit NSNotFound

Zum Beispiel dieser Code:

- (BOOL)doesString:(NSString*)string containString:(NSString*)otherString {
    if([string rangeOfString:otherString].location != NSNotFound)
        return YES;
    else
        return NO;
}

hat seine Probleme:

1) Offensichtlich, wenn otherString = nildieser Code abstürzt. Ein einfacher Test wäre:

NSLog(@"does string contain string - %@", [self doesString:@"hey" containString:nil] ? @"YES": @"NO");

führt zu !! ABSTURZ !!

2) Was für jemanden, der neu in Objective-C ist, nicht so offensichtlich ist, ist, dass derselbe Code NICHT abstürzt, wenn string = nil. Zum Beispiel dieser Code:

NSLog(@"does string contain string - %@", [self doesString:nil containString:@"hey"] ? @"YES": @"NO");

und dieser Code:

NSLog(@"does string contain string - %@", [self doesString:nil containString:nil] ? @"YES": @"NO");

wird beides ergeben

does string contains string - YES

Welches ist eindeutig nicht das, was Sie wollen.

Die bessere Lösung, von der ich glaube, dass sie funktioniert, besteht darin, die Tatsache zu verwenden, dass rangeOfString die Länge 0 zurückgibt. Ein zuverlässigerer Code ist also folgender:

- (BOOL)doesString:(NSString*)string containString:(NSString*)otherString {
    if(otherString && [string rangeOfString:otherString].length)
        return YES;
    else
        return NO;
}

ODER EINFACH:

- (BOOL)doesString:(NSString*)string containString:(NSString*)otherString {
    return (otherString && [string rangeOfString:otherString].length);
}

welches für die Fälle 1 und 2 zurückkehren wird

does string contains string - NO

Das sind meine 2 Cent ;-)

Bitte überprüfen Sie meine Liste für weitere hilfreiche Codes.

ucangetit
quelle
12

Eine verbesserte Version der Lösung von P i , einer Kategorie in NSString, die nicht nur anzeigt, ob eine Zeichenfolge in einer anderen Zeichenfolge gefunden wird, sondern auch einen Referenzbereich verwendet, lautet:

@interface NSString (Contains)
-(BOOL)containsString: (NSString*)substring
              atRange:(NSRange*)range;

-(BOOL)containsString:(NSString *)substring;
@end

@implementation NSString (Contains)

-(BOOL)containsString:(NSString *)substring
              atRange:(NSRange *)range{

    NSRange r = [self rangeOfString : substring];
    BOOL found = ( r.location != NSNotFound );
    if (range != NULL) *range = r;
    return found;
}

-(BOOL)containsString:(NSString *)substring
{
    return [self containsString:substring
                        atRange:NULL];
}

@end

Verwenden Sie es wie:

NSString *string = @"Hello, World!";

//If you only want to ensure a string contains a certain substring
if ([string containsString:@"ello" atRange:NULL]) {
    NSLog(@"YES");
}

// Or simply
if ([string containsString:@"ello"]) {
    NSLog(@"YES");
}

//If you also want to know substring's range
NSRange range;
if ([string containsString:@"ello" atRange:&range]) {
    NSLog(@"%@", NSStringFromRange(range));
}
vikingosegundo
quelle
8

Hier ist ein Funktionsausschnitt zum Kopieren und Einfügen:

-(BOOL)Contains:(NSString *)StrSearchTerm on:(NSString *)StrText
{
    return [StrText rangeOfString:StrSearchTerm 
        options:NSCaseInsensitiveSearch].location != NSNotFound;
}
Durai Amuthan.H
quelle
Darf ich wissen, warum ich abgelehnt werde? Es ist ein funktionierender Code-Ausschnitt
Durai Amuthan.H
6

Oneliner (kleinere Codemenge. TROCKEN, da Sie nur einen haben NSLog):

NSString *string = @"hello bla bla";
NSLog(@"String %@", ([string rangeOfString:@"bla"].location == NSNotFound) ? @"not found" : @"cotains bla"); 
Jerik
quelle
6
NSString *categoryString = @"Holiday Event";
if([categoryString rangeOfString:@"Holiday"].location == NSNotFound)
{
    //categoryString does not contains Holiday
}
else
{
    //categoryString contains Holiday
}
Ada
quelle
5

Versuche dies,

NSString *string = @"test Data";
if ([[string lowercaseString] rangeOfString:@"data"].location == NSNotFound) 
{
    NSLog(@"string does not contain Data");
}   
else 
{
    NSLog(@"string contains data!");
}
Pooja Patel
quelle
5

Beste Lösung. So einfach ist das! Wenn Sie ein Wort oder einen Teil der Zeichenfolge suchen möchten. Sie können diesen Code verwenden. In diesem Beispiel werden wir prüfen, ob der Wert von word "acter" enthält.

NSString *word =@"find a word or character here";
if ([word containsString:@"acter"]){
    NSLog(@"It contains acter");
} else {
     NSLog (@"It does not contain acter");
}
Handiansom
quelle
5

In Swift 4:

let a = "Hello, how are you?"
a.contains("Hello")   //will return true
Ankit garg
quelle
4

Wenn Sie dies einmal brauchen, schreiben Sie:

NSString *stringToSearchThrough = @"-rangeOfString method finds and returns the range of the first occurrence of a given string within the receiver.";
BOOL contains = [stringToSearchThrough rangeOfString:@"occurence of a given string"].location != NSNotFound;
Nikolay Shubenkov
quelle
4

Im Falle einer schnellen kann dies verwendet werden

let string = "Package #23"
if string.containsString("Package #") {
    //String contains substring
}
else {
    //String does not contain substring
}
Sreedeepkesav MS
quelle
2

Wenn Sie sich nicht um Groß- und Kleinschreibung kümmern. Versuchen Sie dies einmal.

NSString *string  = @"Hello World!";

if([string rangeOfString:@"hello" options:NSCaseInsensitiveSearch].location !=NSNotFound)
{
    NSLog(@"found");
}
else
{
    NSLog(@"not found");
}
Abhijit
quelle
1

Bitte benutzen Sie diesen Code

NSString *string = @"hello bla bla";
if ([string rangeOfString:@"bla"].location == NSNotFound) 
{
    NSLog(@"string does not contain bla");
} 
else 
{  
    NSLog(@"string contains bla!");
}
Rohit suvagiya
quelle
1

Verwenden Sie die Option NSCaseInsensitiveSearch mit rangeOfString: options:

NSString *me = @"toBe" ;
NSString *target = @"abcdetobe" ;
NSRange range = [target  rangeOfString: me options: NSCaseInsensitiveSearch];
NSLog(@"found: %@", (range.location != NSNotFound) ? @"Yes" : @"No");
if (range.location != NSNotFound) {
// your code
}

Ausgabeergebnis wird gefunden: Ja

Die Optionen können zusammen "or'ed" sein und umfassen:

NSCaseInsensitiveSearch NSLiteralSearch NSBackwardsSearch und mehr

Nayab Muhammad
quelle
0

Erste Zeichenfolge enthält oder nicht zweite Zeichenfolge,

NSString *first = @"Banana";
NSString *second = @"BananaMilk";
NSRange range = [first rangeOfString:second options:NSCaseInsensitiveSearch];

if (range.length > 0) {
    NSLog(@"Detected");
}
else {
    NSLog(@"Not detected");
}
Kamani Jasmin
quelle
0

Versuche dies:

Swift 4.1, 4.2:

let stringData = "Black board"

//swift quick way and case sensitive
if stringData.contains("bla") {
    print("data contains string");
}

//case sensitive
if stringData.range(of: "bla",options: .caseInsensitive) != nil {
    print("data contains string");
}else {
    print("data does not contains string");
}

Für Ziel-C:

NSString *stringData = @"Black board";

//Quick way and case sensitive
if ([stringData containsString:@"bla"]) {
    NSLog(@"data contains string");
}

//Case Insensitive
if ([stringData rangeOfString:@"bla" options:NSCaseInsensitiveSearch].location != NSNotFound) {
   NSLog(@"data contains string");
}else {
   NSLog(@"data does not contain string");
}
Amir.n3t
quelle
0

Swift 4 und höher

let str = "Hello iam midhun"

if str.contains("iam") {
  //contains substring
}
else {
  //doesn't contain substring
}

Ziel c

NSString *stringData = @"Hello iam midhun";

if ([stringData containsString:@"iam"]) {
    //contains substring
}
else {
    //doesn't contain substring
}
midhun p
quelle
-1
-(Bool)checkIf:(String)parentString containsSubstring:(String)checkString {
    NSRange textRange =[parentString rangeOfString:checkString];
    return textRange.location != NSNotFound // returns true if parent string contains substring else returns false
  }
iOS Nepal
quelle
1
In Objective-C haben wir den Typ 'NSString'. Wir haben keinen StringTyp. Zweitens haben wir alle Objekte. Als Argument sollten Sie also bestehen NSString. Ich stimme für die Löschung aufgrund der schlechten Qualität einer Antwort unter hochaktiven Fragen.
Aleksey Potapov
-2

Wenn eine bestimmte Position der Zeichenfolge benötigt wird, wird dieser Code in Swift 3.0 eingefügt :

let string = "This is my string"
let substring = "my"

let position = string.range(of: substring)?.lowerBound
pedrouan
quelle