É hora de admitir a derrota ...
No Objective-C, eu poderia usar algo como:
NSString* str = @"abcdefghi";
[str rangeOfString:@"c"].location; // 2
Em Swift, vejo algo semelhante:
var str = "abcdefghi"
str.rangeOfString("c").startIndex
... mas isso me dá um String.Index
, que eu posso usar para subscrever de volta na string original, mas não extrair um local.
FWIW, que String.Index
possui um ivar privado chamado _position
que possui o valor correto. Só não vejo como é exposto.
Eu sei que poderia adicionar isso facilmente a String. Estou mais curioso sobre o que estou perdendo nesta nova API.
Respostas:
Você não é o único que não conseguiu encontrar a solução.
String
não implementaRandomAccessIndexType
. Provavelmente porque eles habilitam caracteres com diferentes comprimentos de bytes. É por isso que precisamos usarstring.characters.count
(count
oucountElements
no Swift 1.x) para obter o número de caracteres. Isso também se aplica a posições. O_position
é provavelmente um índice para a matriz matéria de bytes e eles não querem expor isso. OString.Index
objetivo é proteger-nos do acesso a bytes no meio de caracteres.Isso significa que qualquer índice que obtiver devem ser criados a partir de
String.startIndex
ouString.endIndex
(String.Index
implementosBidirectionalIndexType
). Quaisquer outros índices podem ser criados usando métodossuccessor
oupredecessor
.Agora, para nos ajudar com os índices, há um conjunto de métodos (funções no Swift 1.x):
Swift 4.x
Swift 3.0
Swift 2.x
Swift 1.x
Trabalhar com
String.Index
é complicado, mas usar um wrapper para indexar por números inteiros (consulte https://stackoverflow.com/a/25152652/669586 ) é perigoso porque oculta a ineficiência da indexação real.Observe que a implementação da indexação Swift tem o problema de que índices / intervalos criados para uma sequência não podem ser usados com segurança para uma sequência diferente , por exemplo:
Swift 2.x
Swift 1.x
fonte
range
dentrovar range = text.rangeOfString("b")
Collection
tem umtypealias IndexType
. Para matrizes, é definido comoInt
,String
pois é definido comoString.Index
. Matrizes e seqüências de caracteres também podem usar intervalos (para criar sub-matrizes e substrings). O intervalo é um tipo especialRange<T>
. Para strings, éRange<String.Index>
, para matrizesRange<Int>
.Swift 2.0
,distance(text.startIndex, range.startIndex)
tornatext.startIndex.distanceTo(range.startIndex)
String
, exatamente comoNSString
no Foundation, tem um método chamadohasPrefix(_:)
.O Swift 3.0 torna isso um pouco mais detalhado:
Extensão:
No Swift 2.0, isso ficou mais fácil:
Extensão:
Implementação do Swift 1.x:
Para uma solução Swift pura, pode-se usar:
Como uma extensão para
String
:fonte
fonte
Eu encontrei esta solução para swift2:
fonte
Swift 5.0
Swift 4.0
fonte
Não tenho certeza de como extrair a posição de String.Index, mas se você estiver disposto a recorrer a algumas estruturas de Objective-C, poderá fazer a ponte para a objetiva-c e fazê-lo da mesma maneira que costumava.
Parece que alguns métodos NSString ainda não foram (ou talvez não serão) portados para String. Contém também vem à mente.
fonte
bridgeToObjectiveC()
chamada não é necessária. Meu problema parece se manifestar apenas ao chamarrangeOfString
a Swift String existente anteriormente. Parece um problema API ...Aqui está uma extensão limpa de String que responde à pergunta:
Swift 3:
Swift 2.2:
fonte
Você também pode encontrar índices de um caractere em uma única string como esta,
O que fornece o resultado em [String.Distance] ou seja. [Int], como
fonte
Se você deseja usar o NSString familiar, pode declará-lo explicitamente:
Ainda não tenho certeza de como fazer isso no Swift.
fonte
Se você deseja conhecer a posição de um caractere em uma string como um valor int, use isto:
fonte
value of type 'Range<String.Index>?' has no member 'location'
.Eu sei que isso é antigo e uma resposta foi aceita, mas você pode encontrar o índice da string em algumas linhas de código usando:
Algumas outras ótimas informações sobre cordas Swift aqui Cordas em Swift
fonte
find
não está disponível no Swift 3Isso funcionou para mim,
isso funcionou também,
fonte
var str = "abcdef"; str.rangeOfString("c").location
levanta um erro sobre String.Index não ter um membro do local nomeado ...O tipo variável String no Swift contém funções diferentes em comparação com o NSString no Objective-C. E como Sulthan mencionou,
O que você pode fazer é baixar sua variável do tipo String para NSString (isso é válido no Swift). Isso lhe dará acesso às funções no NSString.
fonte
Se você pensar bem, na verdade não precisa da versão Int exata do local. O Range ou mesmo o String.Index são suficientes para obter a substring novamente, se necessário:
fonte
A maneira mais simples é:
No Swift 3 :
fonte
String é um tipo de ponte para NSString, então adicione
ao seu arquivo rápido e use todos os métodos "antigos".
fonte
Em termos de pensamento, isso pode ser chamado de INVERSÃO. Você descobre que o mundo é redondo em vez de plano. "Você realmente não precisa conhecer o ÍNDICE do personagem para fazer as coisas com ele." E como programador em C também achei difícil de aguentar! Sua linha "deixe index = letters.characters.indexOf (" c ")!" é suficiente por si só. Por exemplo, para remover oc você pode usar ... (colar no playground)
No entanto, se você deseja um índice, você precisa retornar um índice real, não um Int como valor Int, exigiria etapas adicionais para qualquer uso prático. Essas extensões retornam um índice, uma contagem de um caractere específico e um intervalo que esse código compatível com plug-in de playground demonstrará.
fonte
Solução completa Swift 4:
OffsetIndexableCollection (String usando o Índice Int)
https://github.com/frogcjn/OffsetIndexableCollection-String-Int-Indexable-
fonte
extensão String {
}
fonte
Swift 5
Encontrar índice de substring
Encontrar índice de caracteres
fonte
Se você estiver procurando uma maneira fácil de obter o índice de Caracteres ou String, faça check-out nesta biblioteca http://www.dollarswift.org/#indexof-char-character-int
Você pode obter o indexOf de uma string usando outra string também ou o padrão regex
fonte
Para obter o índice de uma substring em uma string com o Swift 2:
fonte
In swift 2.0
fonte
fonte
Eu brinco com o seguinte
até que eu entenda o fornecido agora é apenas uma matriz de caracteres
e com
fonte
Se você precisa apenas do índice de um caractere, a solução mais simples e rápida (como já indicado por Pascal) é:
fonte
Sobre o assunto de transformar um
String.Index
em umInt
, esta extensão funciona para mim:Exemplo de uso relevante para esta pergunta:
Importante:
Como você pode ver, ele agrupa grupos de grafemas estendidos e une os caracteres de maneira diferente
String.Index
. Claro, é por isso que temosString.Index
. Você deve ter em mente que esse método considera os clusters como caracteres singulares, o que está mais próximo de corrigir. Se seu objetivo é dividir uma string pelo ponto de código Unicode, essa não é a solução para você.fonte
No Swift 2.0 , a função a seguir retorna uma substring antes de um determinado caractere.
fonte
Você pode encontrar o número de índice de um caractere em uma string com este:
fonte
Na minha perspectiva, a melhor maneira de conhecer a própria lógica está abaixo
fonte