Como verifico se uma string contém outra no Swift?

535

No Objective-Ccódigo para verificar uma substring em um NSStringé:

NSString *string = @"hello Swift";
NSRange textRange =[string rangeOfString:@"Swift"];
if(textRange.location != NSNotFound)
{
    NSLog(@"exists");
}

Mas como faço isso no Swift?

Rajneesh071
fonte
2
@rckoenes Eu sou novo para rápida, eu sei como fazer isso ObjectiveC
Rajneesh071
1
Então, por que você não inicia um playground e experimenta?
precisa
Se você é ainda ao redor, mude a resposta aceita a um por user1021430 ... é correta
Dan Rosenstark

Respostas:

1044

Você pode fazer exatamente a mesma ligação com o Swift:

Swift 4 e Swift 5

No Swift 4 String há uma coleção de Charactervalores, não era assim no Swift 2 e 3, então você pode usar este código mais conciso 1 :

let string = "hello Swift"
if string.contains("Swift") {
    print("exists")
}

Swift 3.0+

var string = "hello Swift"

if string.range(of:"Swift") != nil { 
    print("exists")
}

// alternative: not case sensitive
if string.lowercased().range(of:"swift") != nil {
    print("exists")
}

Swift mais antigo

var string = "hello Swift"

if string.rangeOfString("Swift") != nil{ 
    println("exists")
}

// alternative: not case sensitive
if string.lowercaseString.rangeOfString("swift") != nil {
    println("exists")
}

Espero que seja uma solução útil, já que algumas pessoas, inclusive eu, encontraram alguns problemas estranhos ligando containsString(). 1 1

PS. Não esqueça deimport Foundation

Notas de rodapé

  1. Lembre-se de que o uso de funções de coleção no Strings tem alguns casos extremos que podem fornecer resultados inesperados, por exemplo, ao lidar com emojis ou outros clusters de grafema, como letras acentuadas.
Jens Wirth
fonte
13
A documentação da Apple diz: An NSRange structure giving the location and length in the receiver of the first occurrence of aString. Returns {NSNotFound, 0} if aString is not found or is empty (@"").Portanto, talvez apenas a verificação nilnão funcione corretamente.
Alex
7
string.lowercaseString.rangeOfString ("swift"). location! = NSNotFound. Por favor, leia a documentação .. você não receberá um objeto nulo de volta.
TheCodingArt
4
@TheGamingArt Sim, você vai. O Swift faz uma ida e volta completa para você automaticamente, de forma que, se o NSRange for, {NSNotFound, 0}ele seja representado para você como nulo. Se for um intervalo real, ele será representado para você como um Swift Range (opcional). Legal.
Matt
4
Grr. containsString não está nos documentos, mesmo no Xcode 6.3.1.
Duncan C
19
@TheGoonie: Isso não está chamando NSStringé .rangeOfString(). Este está chamando String's .rangeOfString(), que é declarado comofunc rangeOfString(aString: String, options mask: NSStringCompareOptions = default, range searchRange: Range<Index>? = default, locale: NSLocale? = default) -> Range<Index>?
newacct
192

Maneira da extensão

Swift 4

extension String {
    func contains(find: String) -> Bool{
        return self.range(of: find) != nil
    }
    func containsIgnoringCase(find: String) -> Bool{
        return self.range(of: find, options: .caseInsensitive) != nil
    }
}

var value = "Hello world"

print(value.contains("Hello")) // true
print(value.contains("bo"))    // false

print(value.containsIgnoringCase(find: "hello"))    // true
print(value.containsIgnoringCase(find: "Hello"))    // true
print(value.containsIgnoringCase(find: "bo"))       // false

Geralmente, o Swift 4 contém o método, mas está disponível no iOS 8.0 ou posterior


Swift 3.1

Você pode escrever extensão contains:e containsIgnoringCaseparaString

extension String { 

   func contains(_ find: String) -> Bool{
     return self.range(of: find) != nil
   }

   func containsIgnoringCase(_ find: String) -> Bool{
     return self.range(of: find, options: .caseInsensitive) != nil 
   }
 }

Versão Swift mais antiga

extension String {

    func contains(find: String) -> Bool{
       return self.rangeOfString(find) != nil
     }

    func containsIgnoringCase(find: String) -> Bool{
       return self.rangeOfString(find, options: NSStringCompareOptions.CaseInsensitiveSearch) != nil
     }
}

Exemplo:

var value = "Hello world"

print(value.contains("Hello")) // true
print(value.contains("bo"))    // false

print(value.containsIgnoringCase("hello"))    // true
print(value.containsIgnoringCase("Hello"))    // true
print(value.containsIgnoringCase("bo"))       // false
Maxim Shoustin
fonte
6
ignorar caso de uso de retorno self.rangeOfString (encontrar, opções: NSStringCompareOptions.CaseInsensitiveSearch) = nil!
masgar
1
Não é mais necessário, a menos que você não tenha por Foundationperto ... containsStringfunciona bem.
Dan Rosenstark 29/03
5
para o Swift 3.0. Altere para abaixo: extensão String {func contains (find: String) -> Bool {return self.range (of: find)! = Nil} func containsIgnoringCase (find: String) -> Bool {return self.range (of: find , opções: .caseInsensitive)! = nulo}}
Michael Shang
Para Swift 4 -> extensão String {func contains (find: String) -> Bool {retorna self.range (of: find)! = Nil} func containsIgnoringCase (find: String) -> Bool {retorna self.range (of: find, options: .caseInsensitive)! = nil}}
shokaveli 7/11
50

A partir dos documentos, parece que chamar containsString()uma String deve funcionar:

O tipo String do Swift é feito a ponte sem problemas com a classe NSString da Foundation. Se você estiver trabalhando com a estrutura Foundation no Cocoa ou no Cocoa Touch, toda a API do NSString estará disponível para chamar qualquer valor de String que você criar, além dos recursos de String descritos neste capítulo. Você também pode usar um valor String em qualquer API que exija uma instância NSString.

No entanto, não parece funcionar dessa maneira.

Se você tentar usar someString.containsString(anotherString), você receberá um erro de tempo de compilação informando 'String' does not contain a member named 'containsString'.

Portanto, você tem algumas opções, uma das quais é explicitamente conectar-se Stringao Objective-C usando bridgeToObjectiveC()outras duas que envolvam explicitamente o uso de um NSStringe a final envolve converter o Stringpara umNSString

Ao fazer a ponte, você obtém:

var string = "hello Swift"
if string.bridgeToObjectiveC().containsString("Swift") {
    println("YES")
}

Digitando explicitamente a string como um NSString, você obtém:

var string: NSString = "hello Swift"
if string.containsString("Swift") {
    println("YES")
}

Se você já possui um String, pode inicializar um NSString usando NSString (string :):

var string = "hello Swift"
if NSString(string: string).containsString("Swift") {
    println("YES")
}

E, finalmente, você pode converter um existente Stringem um NSStringcomo abaixo

var string = "hello Swift"
if (string as NSString).containsString("Swift") {
    println("YES")
}
Cezar
fonte
4
O último exemplo (eu não tentei outros) trava para mim no iOS 7 (dispositivo); Os aplicativos Swift devem funcionar perfeitamente no iOS 7. O erro que recebo é [__NSCFString containsString:]: unrecognized selector sent to instance. Além disso, eu não posso encontrar o método containsStringnos docs dev para confirmar se o seu novo para iOS 8.
Jason Leach
Interessante. Eu só testei isso em um playground. Vou tentar mais tarde, quando estiver no meu computador.
Cezar
a terceira e quarta opções são as únicas permitidas pelo compilador. tanto crash para mim em beta 4 no iOS 7.
palmi
38

Outro. Oferece suporte a opções de maiúsculas e minúsculas.

Swift 3.0

struct MyString {
  static func contains(_ text: String, substring: String,
                       ignoreCase: Bool = true,
                       ignoreDiacritic: Bool = true) -> Bool {

    var options = NSString.CompareOptions()

    if ignoreCase { _ = options.insert(NSString.CompareOptions.caseInsensitive) }
    if ignoreDiacritic { _ = options.insert(NSString.CompareOptions.diacriticInsensitive) }

    return text.range(of: substring, options: options) != nil
  }
}

Uso

MyString.contains("Niels Bohr", substring: "Bohr") // true

iOS 9 ou superior

Função insensível a maiúsculas e diacríticas disponível desde o iOS 9.

if #available(iOS 9.0, *) {
  "Für Elise".localizedStandardContains("fur") // true
}
Evgenii
fonte
31

A partir do Xcode 7.1 e Swift 2.1 containsString()está funcionando bem para mim.

let string = "hello swift"
if string.containsString("swift") {
    print("found swift")
}

Swift 4:

let string = "hello swift"
if string.contains("swift") {
    print("found swift")
}

E um exemplo Swift 4 que não diferencia maiúsculas de minúsculas:

let string = "Hello Swift"
if string.lowercased().contains("swift") {
    print("found swift")
}

Ou usando uma Stringextensão que não diferencia maiúsculas de minúsculas :

extension String {
    func containsIgnoreCase(_ string: String) -> Bool {
        return self.lowercased().contains(string.lowercased())
    }
}

let string = "Hello Swift"
let stringToFind = "SWIFT"
if string.containsIgnoreCase(stringToFind) {
    print("found: \(stringToFind)")  // found: SWIFT
}
print("string: \(string)")
print("stringToFind: \(stringToFind)")

// console output:
found: SWIFT
string: Hello Swift
stringToFind: SWIFT
Murray Sagal
fonte
3
você precisa import Foundation, caso contrário isso não funcionará.
Andrii Chernenko 21/03
Ou import UIKitde import Foundationé necessária, pelo menos com iOS 11 e Swift 4.
Murray Sagal
Mas isso diferencia maiúsculas de minúsculas. Como você faz a comparação enquanto ignora o caso. Como em java String.equalsIgnoreCase (anotherString)?
Zulkarnain shah
@zulkarnainshah Adicionei um exemplo à resposta.
Murray Sagal
@MurraySagal Isso ainda não é uma pesquisa que não diferencia maiúsculas de minúsculas. Você está convertendo a sequência original para minúscula e comparando-a explicitamente com uma sequência minúscula. Ele vai fazer o trabalho, mas isso não é a maneira ideal de fazer isso
xá Zulkarnain
22

No Swift 4.2

Usar

func contains(_ str: String) -> Bool

Exemplo

let string = "hello Swift"
let containsSwift = string.contains("Swift")
print(containsSwift) // prints true
Saranjith
fonte
4
Observe que isso exige que você importe o Foundation.
rmaddy
16

> NO SWIFT 3.0

let str = "Hello Swift"
if str.lowercased().contains("Swift".lowercased()) {
    print("String Contains Another String")
} else {
    print("Not Exists")
}

Resultado

String Contains Another String
Ashok R
fonte
15

Você pode fazer isso com muita facilidade no Swift usando o código:

let string = "hello Swift";
let subString = (string as NSString).containsString("Swift")
if(subString){println("Exist")}
Anmol Kukreja
fonte
10

Apenas um adendo às respostas aqui.

Você também pode fazer um teste sem distinção entre maiúsculas e minúsculas usando:

 - (BOOL)localizedCaseInsensitiveContainsString:(NSString *)aString

Exemplo:

    import Foundation

    var string: NSString  =  "hello Swift"
   if string.localizedCaseInsensitiveContainsString("Hello") {
    println("TRUE")
}

ATUALIZAR

Isso faz parte do Foundation Framework para iOS e Mac OS X 10.10.xe fazia parte do 10.10 no momento da postagem original.

Documento gerado: 2014-06-05 12:26:27 -0700 Notas de versão do OS X Copyright © 2014 Apple Inc. Todos os direitos reservados.

Notas de versão do OS X 10.10 Cocoa Foundation Framework

O NSString agora possui os dois métodos de conveniência a seguir:

- (BOOL)containsString:(NSString *)str;

- (BOOL)localizedCaseInsensitiveContainsString:(NSString *)str;

markhunte
fonte
1
Estar ciente que esta abordagem requer iOS 8.
Andrew Ebling
9

Aqui está minha primeira facada nisso no playground rápido. Estendo String fornecendo duas novas funções (contains e containsIgnoreCase)

extension String {
    func contains(other: String) -> Bool{
        var start = startIndex

        do{
            var subString = self[Range(start: start++, end: endIndex)]
            if subString.hasPrefix(other){
                return true
            }

        }while start != endIndex

        return false
    }

    func containsIgnoreCase(other: String) -> Bool{
        var start = startIndex

        do{
            var subString = self[Range(start: start++, end: endIndex)].lowercaseString
            if subString.hasPrefix(other.lowercaseString){
                return true
            }

        }while start != endIndex

        return false
    }
}

Use-o assim

var sentence = "This is a test sentence"
sentence.contains("this")  //returns false
sentence.contains("This")  //returns true
sentence.containsIgnoreCase("this")  //returns true

"This is another test sentence".contains(" test ")    //returns true

Gostaria de receber qualquer feedback :)

Ken
fonte
Próxima etapa: faça desta uma função genérica que funcione em todas as coleções :-) Por exemplo, faça o checkout da função interna beginWith (). Na variante de 'ignorar caso', única minúsculas as cordas de uma vez (vamos lc = other.lowercaseString antes da fazer)
hnh
9

De todas as respostas aqui, acho que elas não funcionam ou são um pouco hackeadas (voltando ao NSString). É muito provável que a resposta correta para isso tenha mudado com as diferentes versões beta.

Aqui está o que eu uso:

let string: String = "hello Swift"
if string.rangeOfString("Swift") != nil
{
    println("exists")
}

O "! = Nil" foi necessário no Beta 5.

user1021430
fonte
6

Olha Você aqui:

let s = "hello Swift"
if let textRange = s.rangeOfString("Swift") {
    NSLog("exists")
}
Stéphane de Luca
fonte
Em algum momento você pode precisar de um formato compacto da seguinte maneira: deixe rangeIfExists = string.rangeOfString ("Swift") ?? falsos que ou retornos falsos como um boolean se não for contida ou o NSRange de outra forma
Stéphane de Luca
5

Você não precisa escrever nenhum código personalizado para isso. A partir da versão 1.2, o Swift já teve todos os métodos que você precisa:

  • obtendo o comprimento da string: count(string) ;
  • verificando se a string contém substring: contains(string, substring) ;
  • verificando se a sequência começa com substring: startsWith(string, substring)
  • e etc.
Max Ivashkevich
fonte
Swift 2 não é o mesmo.
Suragch
2
Swift 2 : string.hasPrefix ("start")
SwiftArchitect
5

Em Swift 3

if((a.range(of: b!, options: String.CompareOptions.caseInsensitive, range: nil, locale: nil)) != nil){
    print("Done")
}
Marie Amida
fonte
4

Aqui está! Pronto para o Xcode 8 e Swift 3.

import UIKit

let mString = "This is a String that contains something to search."
let stringToSearchUpperCase = "String"
let stringToSearchLowerCase = "string"

mString.contains(stringToSearchUpperCase) //true
mString.contains(stringToSearchLowerCase) //false
mString.lowercased().contains(stringToSearchUpperCase) //false
mString.lowercased().contains(stringToSearchLowerCase) //true
Carlitos
fonte
3

string.containsString está disponível apenas na versão 10.10 Yosemite (e provavelmente iOS8). Também a ponte para ObjectiveC falha no 10.9. Você está tentando passar um NSString para NSCFString. Não sei a diferença, mas posso dizer 10.9 barfs ao executar esse código em um aplicativo OS X 10.9.

Aqui estão as diferenças no Swift com 10.9 e 10.10: https://developer.apple.com/library/prerelease/mac/documentation/General/Reference/APIDiffsMacOSX10_10SeedDiff/index.html containsString está disponível apenas na 10.10

O Range of String acima funciona muito bem no 10.9. Estou descobrindo que o desenvolvimento no 10.9 é super estável com o Xcode beta2. Não uso playgrounds nem a versão de linha de comando dos playgrounds. Estou descobrindo se as estruturas adequadas são importadas, o preenchimento automático é muito útil.

Bom tempo
fonte
3

Com e nova sintaxe no swift 4, você pode apenas

string.contains("Swift 4 is the best")

string é sua variável de string

100tomer
fonte
2

Versão Xcode 8 / Swift 3:

let string = "hello Swift"

if let range = string.range(of: "Swift") {
    print("exists at range \(range)")
} else {
    print("does not exist")
}

if let lowercaseRange = string.lowercased().range(of: "swift") {
    print("exists at range \(lowercaseRange)")
} else {
    print("does not exist")
}

Você também pode usar contains:

string.contains("swift") // false
string.contains("Swift") // true
JAL
fonte
2

Verifique se ele contém 'Hello'

let s = "Hello World"

if s.rangeOfString("Hello") != nil {
    print("Yes it contains 'Hello'")
}

fonte
2

Swift 4 maneira de verificar se há substrings, incluindo a importação de estrutura Foundation(ou UIKit) necessária :

import Foundation // or UIKit

let str = "Oh Canada!"

str.contains("Can") // returns true

str.contains("can") // returns false

str.lowercased().contains("can") // case-insensitive, returns true

A menos que Foundation(ou UIKit) a estrutura seja importada, str.contains("Can")ocorrerá um erro do compilador.


Esta resposta está regurgitando a resposta dos manojlds , que está completamente correta. Não tenho ideia de por que tantas respostas passam por tantos problemas para recriar Foundationo String.contains(subString: String)método.

NonCreature0714
fonte
1
// Search string exist in employee name finding.
var empName:NSString! = employeeDetails[filterKeyString] as NSString

Case sensitve search.
let rangeOfSearchString:NSRange! = empName.rangeOfString(searchString, options: NSStringCompareOptions.CaseInsensitiveSearch)

// Not found.
if rangeOfSearchString.location != Foundation.NSNotFound
{
    // search string not found in employee name.
}
// Found
else
{
    // search string found in employee name.
}
abhi
fonte
1

Swift 3: aqui você pode ver minha extensão de pesquisa inteligente para string, que permite fazer uma pesquisa em uma string para ver se ela contém ou talvez para filtrar uma coleção com base em um texto de pesquisa.

https://github.com/magonicolas/Swift-Smart-String-Search

Mago Nicolas Palacios
fonte
0

No iOS 8 e mais recente, você pode usar estes dois NSStringmétodos:

@availability(iOS, introduced=8.0)
func containsString(aString: String) -> Bool

@availability(iOS, introduced=8.0)
func localizedCaseInsensitiveContainsString(aString: String) -> Bool
Rudolf Adamkovič
fonte
O que? parece que não está disponível? na versão que acompanha o xcode 6.1
Ali
0

Encontrei alguns casos de uso interessantes. Essas variantes fazem uso do método rangeOfString e incluo o exemplo de igualdade para mostrar como alguém pode usar melhor os recursos de pesquisa e comparação de Strings no Swift 2.0

//In viewDidLoad() I assign the current object description (A Swift String) to self.loadedObjectDescription
self.loadedObjectDescription = self.myObject!.description

Mais tarde, depois de fazer alterações no self.myObject, posso me referir às seguintes rotinas de comparação de strings (configuradas como variáveis ​​preguiçosas que retornam um Bool). Isso permite verificar o estado a qualquer momento.

lazy var objectHasChanges : Bool = {
        guard self.myObject != nil else { return false }
        return !(self.loadedObjectDescription == self.myObject!.description)
    }()

Uma variante disso acontece quando, às vezes, preciso analisar uma propriedade ausente nesse objeto. Uma pesquisa de cadeias permite-me encontrar uma substring específica sendo definida como nula (o padrão quando um objeto é criado).

    lazy var isMissingProperty : Bool = {
        guard self.myObject != nil else { return true }
        let emptyPropertyValue = "myProperty = nil"
        return (self.myObject!.description.rangeOfString(emptyPropertyValue) != nil) ? true : false
    }()
Tommie C.
fonte
0

Se você quiser verificar se uma String contém outra Sub-String dentro dela ou não, você também pode verificá-la assim,

var name = String()  
name = "John has two apples." 

Agora, nessa sequência específica, se você quiser saber se ela contém o nome da fruta 'maçã' ou não,

if name.contains("apple")      
{  
print("Yes , it contains fruit name")    
}    
else      
{    
 print(it does not contain any fruit name)    
}    

Espero que funcione para voce.

Varsha Shivhare
fonte
-2

Você pode apenas fazer o que você mencionou:

import Foundation
...
string.contains("Swift");

Dos documentos:

O Stringtipo de Swift é unido perfeitamente à NSString classe da Foundation . Se você estiver trabalhando com a estrutura Foundation no Cocoa ou no Cocoa Touch, toda a NSStringAPI estará disponível para chamar qualquer Stringvalor que você criar, além dos recursos de String descritos neste capítulo. Você também pode usar um valor String em qualquer API que exija uma instância NSString.

Você precisa import Foundationconectar os NSStringmétodos e disponibilizá-los para a classe String do Swift.

manojlds
fonte
Não eu, mas não, não.
Cezar
Sim. Tentei em um Playground, em um Mac App e em um aplicativo iOS. Também tentou no Parque importação de cacau, UIKit, Fundação e todas as combinações possíveis de três deles (exceto Cacau / UIKit, que não faz sentido)
Cezar
Este não é o caso, como de Swift 1.2
Kelvin Lau
-4

SWIFT 4 é muito fácil !!

if (yourString.contains("anyThing")) {
   Print("Exist")
}
oscar castellon
fonte
1
Como isso é diferente de várias das outras respostas aqui?
Ashley Mills
1
$ swift Welcome to Apple Swift version 4.2 (swiftlang-1000.11.37.1 clang-1000.11.45.1). Type :help for assistance. 1> print ("Ping") Ping 2> Print ("Ping") error: repl.swift:2:1: error: use of unresolved identifier 'Print' Print ("Ping") ^~~~~ Fornecendo uma resposta não testada que não funciona. Imprimir! = Imprimir.
Fred Gannett