Todos os exemplos a seguir usam
var str = "Hello, playground"
Swift 4
Strings sofreu uma grande reforma no Swift 4. Quando você obtém alguma substring de um String agora, recebe um Substring
tipo de volta em vez de a String
. Por que é isso? Strings são tipos de valor no Swift. Isso significa que, se você usar uma String para criar uma nova, ela deverá ser copiada. Isso é bom para a estabilidade (ninguém mais vai mudar isso sem o seu conhecimento), mas é ruim para a eficiência.
Uma Substring, por outro lado, é uma referência à String original da qual ela veio. Aqui está uma imagem da documentação que ilustra isso.
Nenhuma cópia é necessária, por isso é muito mais eficiente de usar. No entanto, imagine que você tenha um Substring de dez caracteres de um milhão de caracteres. Como a Substring está referenciando a String, o sistema precisaria manter a String inteira enquanto a Substring estiver disponível. Assim, sempre que você terminar de manipular seu Substring, converta-o em uma String.
let myString = String(mySubstring)
Isso copiará apenas a substring e a memória contendo String antiga pode ser recuperada . Substrings (como um tipo) devem durar pouco.
Outra grande melhoria no Swift 4 é que Strings são coleções (novamente). Isso significa que tudo o que você pode fazer em uma coleção, você pode fazer em uma string (use subscritos, itere sobre os caracteres, filtro, etc.).
Os exemplos a seguir mostram como obter uma substring no Swift.
Obtendo substrings
Você pode obter uma substring de uma string usando subscritos ou uma série de outros métodos (por exemplo, prefix
, suffix
, split
). Você ainda precisa usar String.Index
e não um Int
índice para o intervalo. (Veja minha outra resposta se precisar de ajuda com isso.)
Início de uma string
Você pode usar um índice (observe o intervalo unilateral do Swift 4):
let index = str.index(str.startIndex, offsetBy: 5)
let mySubstring = str[..<index] // Hello
ou prefix
:
let index = str.index(str.startIndex, offsetBy: 5)
let mySubstring = str.prefix(upTo: index) // Hello
ou ainda mais fácil:
let mySubstring = str.prefix(5) // Hello
Fim de uma string
Usando subscritos:
let index = str.index(str.endIndex, offsetBy: -10)
let mySubstring = str[index...] // playground
ou suffix
:
let index = str.index(str.endIndex, offsetBy: -10)
let mySubstring = str.suffix(from: index) // playground
ou ainda mais fácil:
let mySubstring = str.suffix(10) // playground
Observe que, ao usar o suffix(from: index)
, tive que contar novamente desde o final usando -10
. Isso não é necessário quando se está usando suffix(x)
, o que leva apenas os últimos x
caracteres de uma String.
Intervalo em uma sequência
Novamente, simplesmente usamos subscritos aqui.
let start = str.index(str.startIndex, offsetBy: 7)
let end = str.index(str.endIndex, offsetBy: -6)
let range = start..<end
let mySubstring = str[range] // play
Convertendo Substring
paraString
Não se esqueça, quando estiver pronto para salvar sua substring, converta-a em um String
para que a memória da string antiga possa ser limpa.
let myString = String(mySubstring)
Usando uma Int
extensão de índice?
Hesito em usar uma Int
extensão de índice baseada depois de ler o artigo Strings in Swift 3 da Airspeed Velocity e Ole Begemann. Embora no Swift 4, Strings sejam coleções, a equipe do Swift propositalmente não usouInt
índices. Ainda estáString.Index
. Isso tem a ver com caracteres Swift sendo compostos por números variáveis de pontos de código Unicode. O índice real deve ser calculado exclusivamente para cada string.
Devo dizer que espero que a equipe Swift encontre uma maneira de abstrair String.Index
no futuro. Mas até eles eu estou escolhendo usar sua API. Isso me ajuda a lembrar que as manipulações de String não são apenas simples Int
pesquisas de índice.