Як перевірити, чи містить рядок інший рядок у Objective-C?


1212

Як я можу перевірити, чи містить рядок ( NSString) інший менший рядок?

Я сподівався на щось на кшталт:

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

Але найближче, що я міг знайти:

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

У будь-якому випадку, це найкращий спосіб дізнатися, чи містить рядок інший рядок?


1
Я також хотів би, щоб це було додано, але тим часом його відносно легко додати як категорію на NSString.
isaac

2
Використання if ([string rangeOfString:@"hello"] == 0) {...}помилки невідповідності типу для NSRange та int. щоб виправити це, слід змінити рядок на наступне:if ([string rangeOfString:@"hello"].length == 0) {...}
Neeku


2
Я розробник iOS з самого початку і постійно переглядаю цю публікацію для швидкого введення копії. Я, здається, не запам’ятав цього. Найпопулярніша публікація stackoverflow в моїй історії.
VaporwareWolf

просто використовуйте Swift;)
Fattie

Відповіді:


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

Ключ помічає, що rangeOfString:повертає NSRangeструктуру, а в документації йдеться про те, що вона повертає структуру, {NSNotFound, 0}якщо "стог сіна" не містить "голки".


А якщо ви перебуваєте на iOS 8 або OS X Yosemite, тепер ви можете зробити це: (* ПРИМІТКА. Це додасть ваші програми, якщо цей код викликається на пристрої iOS7).

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

(Це також, як це працювало б у Swift)

👍


286
Щоб зробити нечутливий до регістру пошук, використовуйте "if ([string rangeOfString: @" bla "параметри: NSCaseInsensitiveSearch] .location! = NSNotFound)"
Vanja

1
@Dave DeLong Я просто збирався згадати категорію, яку я створив для цього, перш ніж прочитати вашу редакцію відповіді! Оскільки я головним чином розробник ac #, я радий, що вони додали метод NSSTring до методу містить.
dherrin79

Чому компілятор нічого не говорить, якщо моя мета розгортання - iOS7, а я використовую містити міститиString?
Рікардо

3
І для подальшого моменту, зробленого @Vanja: якщо ви збираєтесь використовувати код ярлика [string міститьString], який був введений в iOS 8 / Yosemite, ви можете використовувати такий код для нечутливої ​​до регістру рядка: "[stringToSearch localizedCaseInsensitiveContainsString: string ] ", і цей, якщо ви хочете виконати пошук у випадку і діакритичному нечутливому:" [stringToSearch localizedStandardContainsString: string] ".
Скотт Колерт

1
Зауважте, що вираз [string rangeOfString:@"bla"].location != NSNotFoundбуде істинним, коли рядок є nil!
funroll

158

Для iOS 8.0+ та macOS 10.10+ ви можете використовувати натуру NSString containsString:.

Для старих версій iOS та macOS ви можете створити власну (застарілу) категорію для NSString:

@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

Примітка. Дотримуйтесь коментаря Данила Галаско нижче щодо імен


13
+1 для більш чіткого результату коду та використання. Я перетворив його в один вкладиш return [self rangeOfString:substring].location != NSNotFound;і включив його в свою бібліотеку рефакторингу, es_ios_utils. github.com/peterdeweese/es_ios_utils
Peter DeWeese

4
Схоже, Apple подобається вашій ідеї і додав цю функцію в iOS 8 та OSx 10.10 (Yosemite), як @DaveDeLong згадав у своїй відповіді. +1
Іслам Q.

7
Основним правилом для категорій obj-c є префікс назви методу з вашим префіксом 3-буквеного модуля. Це ідеальний приклад, оскільки зараз він суперечить випуску iOS 7 та 10.10
Даніель Галаско

54

Оскільки це здається високим рейтингом у Google, я хочу додати це:

iOS 8 та OS X 10.10 додають containsString:метод до NSString. Оновлена ​​версія прикладу Дейва Делонга для цих систем:

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

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!");
}

// Ви також можете використовувати наступне:

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

22

З iOS 8 та Swift ми можемо використовувати localizedCaseInsensitiveContainsString метод

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

 string.localizedCaseInsensitiveContainsString(substring) // true

1
Це добре. Не маю уявлення, чому у них не було цього методу для ios 7
Лукас

@Lucas, тому що Swift запускався з iOS 8.0. але швидко можна все ще підтримувати пристрої з iOS 7.
Hemang,

13

Тож особисто я дуже ненавиджу, NSNotFoundале розумію його необхідність.

Але деякі люди можуть не розуміти складності порівняння з NSNotFound

Наприклад, цей код:

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

має свої проблеми:

1) Очевидно, якщо otherString = nilцей код вийде з ладу. простим тестом було б:

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

призводить до !! КРИШ !!

2) Що не так очевидно для когось нового в Objective-c, це те, що той самий код НЕ рушиться, коли string = nil. Наприклад, цей код:

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

і цей код:

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

і те, і інше призведе до

does string contains string - YES

Що явно НЕ те, що ви хочете.

Тож краще рішення, на який я вважаю, що працює - це використовувати той факт, що rangeOfString повертає довжину 0, тож краще надійніший код:

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

АБО ПРОСТО:

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

що для випадків 1 і 2 повернеться

does string contains string - NO

Це мої 2 копійки ;-)

Будь ласка, ознайомтеся з моїм істотним документом, щоб отримати корисніший код


12

Вдосконалений варіант Р я рішення «s , категорія на NSString, що не тільки сказати, якщо рядок знаходиться в іншому рядку, але і займає діапазон посилання, є:

@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

Використовуйте його так:

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));
}

8

Ось фрагмент функції копіювання та вставки:

-(BOOL)Contains:(NSString *)StrSearchTerm on:(NSString *)StrText
{
    return [StrText rangeOfString:StrSearchTerm 
        options:NSCaseInsensitiveSearch].location != NSNotFound;
}

Чи можу я знати, чому мене зволікають? Це фрагмент робочого коду
Durai Amuthan.H

6

Oneliner (Менша кількість коду. СУХА, оскільки у вас є лише один NSLog):

NSString *string = @"hello bla bla";
NSLog(@"String %@", ([string rangeOfString:@"bla"].location == NSNotFound) ? @"not found" : @"cotains bla"); 

6
NSString *categoryString = @"Holiday Event";
if([categoryString rangeOfString:@"Holiday"].location == NSNotFound)
{
    //categoryString does not contains Holiday
}
else
{
    //categoryString contains Holiday
}

5

спробуйте це,

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

5

Найкраще рішення. Так просто, як це! Якщо ви хочете знайти слово або частину рядка. Ви можете використовувати цей код. У цьому прикладі ми перевіримо, чи містить слово слово "acter".

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


4

Якщо вам потрібно це один раз, напишіть:

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;

4

У разі швидкого використання це можна використати

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

2

Якщо не турбуйтеся про регістр, що відрізняється від регістру. Спробуйте це один раз.

NSString *string  = @"Hello World!";

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

1

Будь ласка, використовуйте цей код

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

1

Використовуйте опцію NSCaseInsensitiveSearch with 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
}

Вихідний результат знайдений: Так

Опції можуть бути "або '" разом і включати:

NSCaseInsensitiveSearch NSLiteralSearch NSBackwardsSearch та багато іншого


0

Перший рядок містить або не другий рядок,

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

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

0

Спробуйте це:

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");
}

Для Objective-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");
}

0

Швидкий 4 і вище

let str = "Hello iam midhun"

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

Ціль-С

NSString *stringData = @"Hello iam midhun";

if ([stringData containsString:@"iam"]) {
    //contains substring
}
else {
    //doesn't contain substring
}

-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
  }

1
У Objective-C маємо тип "NSString". У нас немає Stringтипу. По-друге, у нас є всі об’єкти. Тож як аргумент вам слід передати NSString. Я голосую за вилучення через низьку якість відповіді під високоактивним питанням.
Олексій Потапов

-2

Якщо потрібне певне положення рядка, цей код приходить в Swift 3.0 :

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

let position = string.range(of: substring)?.lowerBound
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.