Como verifico se uma string contém outra no Objective-C?


1212

Como posso verificar se uma string ( NSString) contém outra string menor?

Eu esperava algo como:

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

Mas o mais próximo que pude encontrar foi:

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

Enfim, essa é a melhor maneira de descobrir se uma string contém outra string?


1
Eu gostaria de vê-lo adicionado também, mas, entretanto, é relativamente fácil adicioná-lo como uma categoria no NSString.
— Isaac

2
Usando if ([string rangeOfString:@"hello"] == 0) {...}há um erro de incompatibilidade de tipo para NSRange e int. para corrigir isso, você deve alterar a linha para o seguinte:if ([string rangeOfString:@"hello"].length == 0) {...}
— Neeku 11/11/13

1
iOS 8 acrescenta containsString: e aqui é uma maneira minimamente invasiva para adicionar iOS 7 suporte petersteinberger.com/blog/2014/...
— Steve Moser

2
Sou desenvolvedor iOS desde o início e revisito constantemente este post para uma pasta de cópia rápida. Não consigo memorizar este. O stackoverflow mais visitado do meu histórico.
— VaporwareWolf

basta usar Swift;)
— Fattie

Respostas:


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

A chave é perceber que rangeOfString:retorna uma NSRangeestrutura e a documentação diz que ela retornará a estrutura {NSNotFound, 0}se o "palheiro" não contiver a "agulha".


E se você estiver no iOS 8 ou no OS X Yosemite, agora pode: (* NOTA: Isso travará seu aplicativo se esse código for chamado em um dispositivo iOS7).

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

(Também é assim que funcionaria no Swift)

👍


286
Para fazer uma pesquisa sem distinção entre maiúsculas e minúsculas, use "if ([string rangeOfString: @" bla "opções: NSCaseInsensitiveSearch] .location! = NSNotFound)"
— Vanja

1
@ Dave DeLong Eu estava indo apenas para mencionar uma categoria que eu criei para esse fim antes de ler sua edição para a resposta! Desde que eu sou principalmente desenvolvedor ac #, fico feliz que eles adicionaram um método contains ao NSSTring.
— precisa saber é o seguinte

Por que o compilador não diz nada se meu destino de implantação é o iOS7 e eu uso containsString?
— Ricardo

3
E para aprofundar o argumento de @Vanja: se você usar o código de atalho [string containsString] que foi introduzido no iOS 8 / Yosemite, poderá usar o seguinte código para uma sequência que não diferencia maiúsculas de minúsculas: "[stringToSearch localizedCaseInsensitiveContainsString: string ] ", e este se você desejar fazer uma pesquisa sem distinção entre maiúsculas e minúsculas e diacrítico:" [stringToSearch localizedStandardContainsString: string] ".
— Scott Kohlert 28/03

1
Observe que a expressão [string rangeOfString:@"bla"].location != NSNotFoundserá verdadeira quando string for nil!
— funroll

158

Para iOS 8.0+ e macOS 10.10+, você pode usar o nativo do NSString containsString:.

Para versões mais antigas do iOS e macOS, você pode criar sua própria categoria (obsoleta) para o 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

Nota: Observe o comentário de Daniel Galasko abaixo sobre nomeação


13
+1 para obter um código resultante mais claro e reutilizável. Eu o transformei no liner único return [self rangeOfString:substring].location != NSNotFound;e o incluí na minha biblioteca de refatoração, es_ios_utils. github.com/peterdeweese/es_ios_utils
— Peter DeWeese

4
Parece que a Apple gostou da sua ideia e adicionou esse recurso no iOS 8 e OSx 10.10 (Yosemite) como @DaveDeLong mencionado em sua resposta. +1
— Islam Q.

7
A regra principal para as categorias obj-c é prefixar o nome do método com o prefixo do módulo de 3 letras. Este é o exemplo perfeito, pois agora entra em conflito com o iOS 7 e 10.10
— Daniel Galasko

54

Como esse parece ser um resultado de alta classificação no Google, quero adicionar o seguinte:

O iOS 8 e o OS X 10.10 adicionam o containsString:método a NSString. Uma versão atualizada do exemplo de Dave DeLong para esses sistemas:

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

// Como alternativa, você também pode usar o seguinte:

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

22

Com o iOS 8 e o Swift , podemos usar o localizedCaseInsensitiveContainsString método

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

 string.localizedCaseInsensitiveContainsString(substring) // true

1
Isso é bom. Não faço ideia por que eles não tinham esse método para o iOS 7
— Lucas

@ Lucas, porque o Swift foi lançado com o iOS 8.0. mas com rápida você ainda pode suportar os dispositivos com iOS 7.
— Hemang

13

Então, pessoalmente, eu realmente odeio, NSNotFoundmas entendo sua necessidade.

Mas algumas pessoas podem não entender as complexidades da comparação com o NSNotFound

Por exemplo, este código:

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

tem seus problemas:

1) Obviamente, se otherString = nileste código falhar. um teste simples seria:

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

resulta em !! BATIDA !!

2) O que não é tão óbvio para alguém novo no objetivo-c é que o mesmo código NÃO trava quando string = nil. Por exemplo, este código:

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

e este código:

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

ambos resultarão em

does string contains string - YES

O que claramente não é o que você deseja.

Portanto, a melhor solução que eu acredito que funciona é usar o fato de rangeOfString retornar o comprimento 0, então um código melhor e mais confiável é o seguinte:

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

OU SIMPLESMENTE:

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

que retornará para os casos 1 e 2

does string contains string - NO

Esses são meus 2 centavos ;-)

Verifique meu Gist para obter mais códigos úteis.


12

Uma versão aprimorada da solução de Pi , uma categoria no NSString, que não apenas informa se uma string é encontrada em outra string, mas também usa um intervalo por referência, é:

@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

Use-o como:

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

Aqui está um trecho de função de copiar e colar:

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

Posso saber por que estou com voto negativo? É um trecho de código que funciona.
— Durai Amuthan

6

Oneliner (menor quantidade de código. SECO, pois você possui apenas um 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

tente isso,

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

5

Melhor solução. Tão simples como isso! Se você deseja encontrar uma palavra ou parte da string. Você pode usar esse código. Neste exemplo, vamos verificar se o valor da palavra contém "acter".

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

5

No Swift 4:

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

4

Se você precisar disso, escreva uma vez:

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

Em caso de rápida, isso pode ser usado

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

2

Se não se preocupe com a seqüência que diferencia maiúsculas de minúsculas. Tente isso uma vez.

NSString *string  = @"Hello World!";

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

1

Por favor use este código

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

1

Use a opção NSCaseInsensitiveSearch com 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
}

Resultado da saída encontrado: Sim

As opções podem ser "or'ed" juntas e incluem:

NSCaseInsensitiveSearch NSLiteralSearch NSBackwardsSearch e mais


0

A primeira string contém ou não a segunda string,

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

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

0

Tente o seguinte:

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

Para 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

Swift 4 e acima

let str = "Hello iam midhun"

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

Objetivo-C

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
No Objective-C, temos o tipo 'NSString`. Nós não temos Stringtipo. Em segundo lugar, temos todos os objetos. Então, como argumento, você deve passar NSString. Eu voto pela exclusão devido à má qualidade de uma resposta sob uma pergunta altamente ativa.
— Aleksey Potapov

-2

Se for necessária uma certa posição da string, esse código ocorrerá no Swift 3.0 :

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

let position = string.range(of: substring)?.lowerBound
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.