Saya belum bisa menemukan cara untuk mendapatkan substring dari String
dalam Swift:
var str = “Hello, playground”
func test(str: String) -> String {
return str.substringWithRange( /* What goes here? */ )
}
test (str)
Saya tidak dapat membuat Range di Swift. Pelengkapan otomatis di Playground tidak super membantu - inilah yang disarankan:
return str.substringWithRange(aRange: Range<String.Index>)
Saya belum menemukan apa pun di Perpustakaan Referensi Standar Swift yang membantu. Inilah satu lagi tebakan liar:
return str.substringWithRange(Range(0, 1))
Dan ini:
let r:Range<String.Index> = Range<String.Index>(start: 0, end: 2)
return str.substringWithRange(r)
Saya telah melihat jawaban lain ( Mencari indeks karakter dalam Swift String ) yang tampaknya menyarankan bahwa karena String
merupakan tipe jembatan untuk NSString
, metode "lama" harus bekerja, tetapi tidak jelas bagaimana - misalnya, ini tidak berhasil juga ( tampaknya bukan sintaks yang valid):
let x = str.substringWithRange(NSMakeRange(0, 3))
Pikiran?
Jawaban:
Anda dapat menggunakan metode substringWithRange. Dibutuhkan awal dan akhir String.Index.
Untuk mengubah indeks awal dan akhir, gunakan advancedBy (n).
Anda juga masih dapat menggunakan metode NSString dengan NSRange, tetapi Anda harus memastikan bahwa Anda menggunakan NSString seperti ini:
Catatan: seperti yang disebutkan JanX2, metode kedua ini tidak aman dengan string unicode.
sumber
advance
berarti kita harus mengulanginya sepanjang string yang mungkin panjang. Tetapi membentuk NSRange dan menggunakan NSString secara eksplisit berbahaya? Apa yang tersisaCepat 2
Sederhana
Cepat 3
Cepat 4
substring(to:)
dansubstring(from:)
tidak digunakan lagi diSwift 4
.sumber
CATATAN: @airspeedswift membuat beberapa poin yang sangat mendalam tentang pertukaran dari pendekatan ini, khususnya dampak kinerja yang tersembunyi. String bukanlah beast yang sederhana, dan mencapai indeks tertentu mungkin membutuhkan waktu O (n), yang berarti sebuah loop yang menggunakan subskrip dapat berupa O (n ^ 2). Anda telah diperingatkan.
Anda hanya perlu menambahkan
subscript
fungsi baru yang mengambil rentang dan gunakanadvancedBy()
untuk berjalan ke tempat yang Anda inginkan:(Ini pasti harus menjadi bagian dari bahasa. Tolong ditipu rdar: // 17158813 )Untuk bersenang-senang, Anda juga dapat menambahkan
+
operator ke indeks:(Saya belum tahu apakah ini harus menjadi bagian dari bahasa atau tidak.)
sumber
advance<T>(…)
diSwift
namespace.String.Index
. Dalam hal ini, ini bukan optimasi sebanyak itu menjaga semuanya mudah. Harus berganti-ganti antara int dan String .Index bolak-balik di mana-mana akan menyebabkan kekacauan.String.Index
es) yang sering terjadi. Daripada Anda bisa berharap semua metode penanganan string itu bekerja denganInt
s. Dan Anda terpaksa mengonversinyaString.Indexes
yang mengarah ke kekacauan yang Anda sebutkan.Pada saat saya sedang menulis, tidak ada ekstensi yang kompatibel dengan Swift 4.2 , jadi ini adalah salah satu yang mencakup semua kebutuhan yang dapat saya pikirkan:
Dan kemudian, Anda dapat menggunakan:
string.substring(from: 1, to: 7)
memberi Anda:ello,Wo
string.substring(to: 7)
memberi Anda:Hello,Wo
string.substring(from: 3)
memberi Anda:lo,World!
string.substring(from: 1, length: 4)
memberi Anda:ello
string.substring(length: 4, to: 7)
memberi Anda:o,Wo
Diperbarui
substring(from: Int?, length: Int)
untuk mendukung mulai dari nol.sumber
"Hello😇😍😘😎📸📀💾∝ℵℶ≹".substring(from: 4, to: 14)
memberi kita:o😇😍😘😎📸📀💾∝ℵℶ
SWIFT 2.0
sederhana:
SWIFT 3.0
SWIFT 4.0
Operasi Substring mengembalikan turunan dari jenis Substring, bukan String.
sumber
text[text.startIndex..<text.index(text.startIndex, offsetBy: 2)]
Ini jauh lebih sederhana daripada jawaban apa pun di sini, setelah Anda menemukan sintaks yang tepat.
Saya ingin mengambil [dan]
hasilnya adalah "ABCDEFGHI", startIndex dan endIndex juga dapat digunakan di
dan seterusnya!
PS: Seperti yang ditunjukkan dalam komentar, ada beberapa perubahan sintaks di swift 2 yang datang dengan xcode 7 dan iOS9!
Silakan lihat halaman ini
sumber
advance(myString.endIndex, -1)
sintaks Xcode 7 beta 6 telah berubah menjadimyString.endIndex.advancedBy(-1)
Misalnya untuk menemukan nama depan (hingga spasi pertama) dalam nama lengkap saya:
start
danend
bertipe diString.Index
sini dan digunakan untuk membuatRange<String.Index>
dan digunakan di accessor subskrip (jika ruang ditemukan sama sekali dalam string asli).Sulit untuk membuat
String.Index
langsung dari posisi bilangan bulat seperti yang digunakan dalam pos pembuka. Ini karena dalam nama saya setiap karakter akan memiliki ukuran yang sama dalam byte. Tetapi karakter yang menggunakan aksen khusus dalam bahasa lain dapat menggunakan beberapa byte lagi (tergantung pada pengkodean yang digunakan). Jadi byte apa yang harus merujuk integer?Dimungkinkan untuk membuat yang baru
String.Index
dari yang sudah ada menggunakan metodesucc
danpred
yang akan memastikan jumlah byte yang benar dilewati untuk sampai ke titik kode berikutnya dalam pengkodean. Namun dalam hal ini lebih mudah untuk mencari indeks spasi pertama dalam string untuk menemukan indeks akhir.sumber
Bagi saya, itu adalah bagian yang sangat menarik dari pertanyaan Anda. String adalah bridge ke NSString, sehingga sebagian besar metode NSString melakukan pekerjaan langsung pada String. Anda dapat menggunakannya secara bebas dan tanpa berpikir. Jadi, misalnya, ini berfungsi seperti yang Anda harapkan:
Tetapi, seperti yang sering terjadi, "Saya mendapat mojo saya bekerja tetapi itu tidak berhasil pada Anda." Anda kebetulan mengambil salah satu kasus langka di mana paralel bernama identik metode Swift ada , dan dalam kasus seperti itu, metode Swift menaungi metode Objective-C. Jadi, ketika Anda mengatakan
str.substringWithRange
, Swift menganggap maksud Anda metode Swift daripada metode NSString - dan kemudian Anda disemprot, karena metode Swift mengharapkan aRange<String.Index>
, dan Anda tidak tahu cara membuat salah satunya.Jalan keluar yang mudah adalah menghentikan Swift dari menaungi seperti ini, dengan melemparkan secara eksplisit:
Perhatikan bahwa tidak ada pekerjaan tambahan yang signifikan yang terlibat di sini. "Cast" tidak berarti "convert"; String secara efektif merupakan NSString. Kami hanya memberi tahu Swift cara melihat variabel ini untuk keperluan satu baris kode ini.
Bagian yang sangat aneh dari semua ini adalah bahwa metode Swift, yang menyebabkan semua masalah ini, tidak didokumentasikan. Saya tidak tahu di mana itu didefinisikan; itu tidak di header NSString dan juga tidak di header Swift.
sumber
Range<String.Index>
, atau mengeluarkan metode tidak berdokumen ini dari cara kita.Dalam penggunaan Xcode 7.0 baru
sumber
.advancedBy(0)
tidak diperlukan untuk startIndex.Jawaban singkatnya adalah bahwa ini sangat sulit di Swift sekarang. Firasat saya adalah bahwa masih ada banyak pekerjaan untuk Apple untuk dilakukan pada metode kenyamanan untuk hal-hal seperti ini.
String.substringWithRange()
mengharapkanRange<String.Index>
parameter, dan sejauh yang saya tahu tidak ada metode generator untukString.Index
tipe tersebut. Anda dapat memperolehString.Index
nilai kembali dariaString.startIndex
danaString.endIndex
dan menelepon.succ()
atau.pred()
pada mereka, tapi itu gila.Bagaimana dengan ekstensi pada kelas String yang membutuhkan waktu lama
Int
?Memperbarui: Swift beta 4 menyelesaikan masalah di bawah ini!
Seperti berdiri [dalam beta 3 dan sebelumnya], bahkan string Swift-asli memiliki beberapa masalah dengan penanganan karakter Unicode. Ikon anjing di atas berfungsi, tetapi yang berikut tidak:
Keluaran:
sumber
NSString
membuat saya berpikir saya hanya menggunakanString
metode Swift-asli , karena saya tidak menggunakanmyString as NSString
panggilan apa pun .Anda dapat menggunakan ekstensi ini untuk meningkatkan
substringWithRange
Cepat 2.3
Cepat 3
Pemakaian:
sumber
Kode Contoh untuk cara mendapatkan substring di Swift 2.0
(i) Substring dari indeks awal
Memasukkan:-
Keluaran:-
(ii) Substring dari indeks tertentu
Memasukkan:-
Keluaran:-
Saya harap ini akan membantu Anda!
sumber
Solusi mudah dengan kode kecil.
Buat ekstensi yang mencakup subString dasar yang dimiliki hampir semua bahasa lainnya:
Cukup panggil ini dengan
sumber
Ini bekerja di taman bermain saya :)
sumber
advance
Diperbarui untuk Xcode 7. Menambahkan ekstensi String:
Menggunakan:
Penerapan:
sumber
coba ini di taman bermain
itu akan memberi Anda "ello, p"
Namun di mana ini menjadi sangat menarik adalah bahwa jika Anda membuat indeks terakhir lebih besar dari string di taman bermain itu akan menunjukkan string apa pun yang Anda tetapkan setelah str: o
Range () tampaknya merupakan fungsi generik sehingga perlu mengetahui tipe yang dihadapinya.
Anda juga harus memberikan string yang sebenarnya Anda minati di taman bermain karena tampaknya menyimpan semua sengatan secara berurutan dengan nama variabel mereka sesudahnya.
Begitu
memberikan "ello, playground str I'm string str2 berikutnya"
berfungsi bahkan jika str2 didefinisikan dengan let
:)
sumber
Rob Napier sudah memberikan jawaban yang bagus menggunakan subskrip. Tapi saya merasakan satu kekurangan dalam hal itu karena tidak ada pemeriksaan untuk kondisi di luar batas. Ini bisa cenderung macet. Jadi saya memodifikasi ekstensi dan ini dia
Output di bawah
Jadi saya sarankan untuk selalu memeriksa jika biarkan
sumber
Di Swift3
Sebagai contoh: variabel "Duke James Thomas", kita perlu mendapatkan "James".
sumber
Mengambil halaman dari Rob Napier, saya mengembangkan Common String Extensions ini , dua di antaranya adalah:
Pemakaian:
sumber
Range
sebagai gantiRange<String.Index>
terima kasih untuk mengetik inferensi.Ini adalah cara Anda mendapatkan rentang dari string:
Poin kuncinya adalah bahwa Anda melewati serangkaian nilai dari tipe String.Index (ini adalah apa yang mengembalikan muka) bukan bilangan bulat.
Alasan mengapa ini diperlukan, adalah bahwa string di Swift tidak memiliki akses acak (karena panjang variabel karakter Unicode pada dasarnya). Anda juga tidak bisa melakukannya
str[1]
. String.Index dirancang untuk bekerja dengan struktur internal mereka.Anda dapat membuat ekstensi dengan subskrip, yang melakukan ini untuk Anda, jadi Anda bisa melewati serangkaian bilangan bulat (lihat misalnya jawaban Rob Napier ).
sumber
Saya mencoba membuat sesuatu Pythonic.
Semua subskrip di sini hebat, tetapi saat saya benar-benar membutuhkan sesuatu yang sederhana biasanya ketika saya ingin menghitung dari belakang, misalnya
string.endIndex.advancedBy(-1)
Ini mendukung
nil
nilai, untuk indeks awal dan akhir, di mananil
berarti indeks pada 0 untuk awal,string.characters.count
untuk akhir.EDIT
Solusi yang lebih elegan:
sumber
Pertama buat rentang, lalu substring. Anda dapat menggunakan
fromIndex..<toIndex
sintaks seperti:sumber
berikut adalah contoh untuk mendapatkan video-Id saja .ie (6oL687G0Iso) dari seluruh URL dengan cepat
sumber
Sampel lengkap bisa Anda lihat di sini
sumber
http://www.learnswiftonline.com/reference-guides/string-reference-guide-for-swift/ menunjukkan bahwa ini bekerja dengan baik:
sumber
Yah, saya punya masalah yang sama dan diselesaikan dengan fungsi "bridgeToObjectiveC ()":
Harap perhatikan bahwa dalam contoh, substringWithRange bersamaan dengan NSMakeRange ambil bagian dari string mulai dari indeks 6 (karakter "W") dan berakhir pada indeks 6 + 6 posisi di depan (karakter "!")
Bersulang.
sumber
Anda dapat menggunakan salah satu metode substring dalam ekstensi Swift String yang saya tulis https://bit.ly/JString .
sumber
Jika Anda memiliki
NSRange
, menjembatani untukNSString
bekerja dengan lancar. Sebagai contoh, saya melakukan beberapa pekerjaan denganUITextFieldDelegate
dan saya dengan cepat ingin menghitung nilai string baru ketika ditanya apakah harus mengganti rentang.sumber
Ekstensi sederhana untuk
String
:sumber
Jika Anda tidak peduli dengan kinerja ... ini mungkin solusi paling ringkas di Swift 4
Ini memungkinkan Anda untuk melakukan sesuatu seperti ini:
sumber