Sekalipun matchesInString()
metode tersebut menggunakan String
argumen pertama, ia bekerja secara internal NSString
, dan parameter rentang harus diberikan menggunakan NSString
panjang dan bukan sebagai panjang string Swift. Kalau tidak, itu akan gagal untuk "cluster grapheme diperpanjang" seperti "bendera".
Pada Swift 4 (Xcode 9), perpustakaan standar Swift menyediakan fungsi untuk mengkonversi antara Range<String.Index>
dan NSRange
.
func matches(for regex: String, in text: String) -> [String] {
do {
let regex = try NSRegularExpression(pattern: regex)
let results = regex.matches(in: text,
range: NSRange(text.startIndex..., in: text))
return results.map {
String(text[Range($0.range, in: text)!])
}
} catch let error {
print("invalid regex: \(error.localizedDescription)")
return []
}
}
Contoh:
let string = "π©πͺβ¬4β¬9"
let matched = matches(for: "[0-9]", in: string)
print(matched)
// ["4", "9"]
Catatan: Bukaan paksa Range($0.range, in: text)!
aman karena NSRange
mengacu pada substring dari string yang diberikan text
. Namun, jika Anda ingin menghindarinya maka gunakan
return results.flatMap {
Range($0.range, in: text).map { String(text[$0]) }
}
sebagai gantinya.
(Jawaban yang lebih lama untuk Swift 3 dan sebelumnya :)
Jadi, Anda harus mengubah string Swift yang diberikan ke NSString
dan kemudian mengekstrak rentang. Hasilnya akan dikonversi ke array string Swift secara otomatis.
(Kode untuk Swift 1.2 dapat ditemukan di riwayat edit.)
Swift 2 (Xcode 7.3.1):
func matchesForRegexInText(regex: String, text: String) -> [String] {
do {
let regex = try NSRegularExpression(pattern: regex, options: [])
let nsString = text as NSString
let results = regex.matchesInString(text,
options: [], range: NSMakeRange(0, nsString.length))
return results.map { nsString.substringWithRange($0.range)}
} catch let error as NSError {
print("invalid regex: \(error.localizedDescription)")
return []
}
}
Contoh:
let string = "π©πͺβ¬4β¬9"
let matches = matchesForRegexInText("[0-9]", text: string)
print(matches)
// ["4", "9"]
Swift 3 (Xcode 8)
func matches(for regex: String, in text: String) -> [String] {
do {
let regex = try NSRegularExpression(pattern: regex)
let nsString = text as NSString
let results = regex.matches(in: text, range: NSRange(location: 0, length: nsString.length))
return results.map { nsString.substring(with: $0.range)}
} catch let error {
print("invalid regex: \(error.localizedDescription)")
return []
}
}
Contoh:
let string = "π©πͺβ¬4β¬9"
let matched = matches(for: "[0-9]", in: string)
print(matched)
// ["4", "9"]
Jawaban saya dibangun di atas jawaban yang diberikan tetapi membuat pencocokan regex lebih kuat dengan menambahkan dukungan tambahan:
do/catch
dengan tidak mencetak ke konsol dan memanfaatkanguard
konstrukmatchingStrings
sebagai ekstensi keString
Cepat 4.2
Cepat 3
Cepat 2
sumber
try?
dapat digunakan jika Anda hanya tertarik pada hasil panggilan, bukan pada pesan kesalahan yang mungkin. Jadi ya,guard try? ..
baik-baik saja, tetapi jika Anda ingin mencetak kesalahan maka Anda perlu melakukan blokir. Kedua cara itu Swifty.Jika Anda ingin mengekstraksi substring dari sebuah String, bukan hanya posisinya, (tetapi String yang sebenarnya termasuk emoji). Lalu, berikut ini mungkin solusi yang lebih sederhana.
Contoh penggunaan:
Akan mengembalikan yang berikut:
Catatan menggunakan "\ w +" dapat menghasilkan yang tidak terduga ""
Akan mengembalikan array String ini
sumber
Saya menemukan bahwa solusi jawaban yang diterima sayangnya tidak dapat dikompilasi pada Swift 3 untuk Linux. Inilah versi yang dimodifikasi, yang artinya:
Perbedaan utama adalah:
Swift di Linux tampaknya perlu menjatuhkan
NS
awalan pada objek Foundation yang tidak ada padanan asli Swift. (Lihat proposal evolusi Swift # 86. )Swift di Linux juga membutuhkan spesifikasi
options
argumen untukRegularExpression
inisialisasi danmatches
metode.Untuk beberapa alasan, memaksa
String
menjadiNSString
tidak berfungsi di Swift di Linux tetapi menginisialisasi yang baruNSString
denganString
sebagai sumber tidak bekerja.Versi ini juga berfungsi dengan Swift 3 di macOS / Xcode dengan satu-satunya pengecualian bahwa Anda harus menggunakan nama dan
NSRegularExpression
bukanRegularExpression
.sumber
@ p4bloch jika Anda ingin mengambil hasil dari serangkaian tanda kurung, maka Anda perlu menggunakan
rangeAtIndex(index)
metodeNSTextCheckingResult
, alih-alihrange
. Inilah metode @MartinR untuk Swift2 dari atas, diadaptasi untuk menangkap tanda kurung. Dalam larik yang dikembalikan, hasil pertama[0]
adalah seluruh tangkapan, dan kemudian masing-masing kelompok tangkapan dimulai[1]
. Saya berkomentarmap
operasi (jadi lebih mudah untuk melihat apa yang saya ubah) dan menggantinya dengan loop bersarang.Contoh use case mungkin, katakan Anda ingin membagi string
title year
mis. "Finding Dory 2016" Anda bisa melakukan ini:sumber
[String?]
dan difor i in 0..<result.numberOfRanges
blok, Anda harus menambahkan tes yang hanya menambahkan kecocokan jika rentang! =NSNotFound
, Jika tidak, ia harus menambahkan nol. Lihat: stackoverflow.com/a/31892241/2805570Swift 4 tanpa NSString.
sumber
NSMakeRange(0, self.count)
tidak benar, karenaself
adalahString
(= UTF8) dan bukanNSString
(= UTF16). Jadiself.count
belum tentu sama dengannsString.length
(seperti yang digunakan dalam solusi lain). Anda dapat mengganti perhitungan rentang denganNSRange(self.startIndex..., in: self)
Sebagian besar solusi di atas hanya memberikan kecocokan penuh sebagai hasilnya mengabaikan kelompok tangkapan misalnya: ^ \ d + \ s + (\ d +)
Untuk mendapatkan pertandingan grup tangkapan seperti yang diharapkan, Anda memerlukan sesuatu seperti (Swift4):
sumber
for index in 0..<matches.count {
sekitarlet lastRange... results.append(matchedString)}
for i in 1...lastRangeIndex { let capturedGroupIndex = match.range(at: i) if capturedGroupIndex.location != NSNotFound { let matchedString = (self as NSString).substring(with: capturedGroupIndex) results.append(matchedString.trimmingCharacters(in: .whitespaces)) } }
Inilah yang saya lakukan, saya harap ini membawa perspektif baru bagaimana ini bekerja pada Swift.
Dalam contoh di bawah ini saya akan mendapatkan string apa pun di antaranya
[]
sumber
Ini adalah solusi yang sangat sederhana yang mengembalikan array string dengan korek api
Cepat 3.
sumber
Cara tercepat untuk mengembalikan semua pertandingan dan menangkap grup di Swift 5
Mengembalikan deretan string 2-dimensi:
mengembalikan ...
sumber
Terima kasih kepada Lars Blumberg nya jawaban untuk menangkap kelompok dan pertandingan penuh dengan Swift 4 , yang membantu saya keluar banyak. Saya juga membuat tambahan untuk orang-orang yang menginginkan respons error.localizedDescription ketika regex mereka tidak valid:
Bagi saya memiliki deskripsi localizedDescription sebagai kesalahan membantu memahami apa yang salah dengan melarikan diri, karena menampilkan yang regex terakhir yang coba diimplementasikan dengan cepat.
sumber