Ekspresi reguler dalam aplikasi Kakao Objective-C

173

Googling Awal menunjukkan bahwa tidak ada cara bawaan untuk melakukan ekspresi reguler dalam aplikasi Kakao Objective-C.

Jadi empat pertanyaan:

  1. Benarkah itu benar?

  2. Apakah kamu bercanda?

  3. Oke, lalu adakah perpustakaan sumber terbuka yang bagus yang Anda rekomendasikan?

  4. Apa cara untuk cukup dekat tanpa mengimpor perpustakaan, mungkin dengan kelas NSScanner?

Dreeves
sumber
4
Hmmmm ... Saya ingin tahu apa yang terjadi jika Anda menggunakan Monotouch. +1 untuk pertanyaan.
Dan Rosenstark

Jawaban:

42
  1. Ya, tidak ada dukungan regex di Kakao. Jika Anda hanya tertarik pada pencocokan boolean, Anda dapat menggunakan NSPredicate yang mendukung sintaksis ICU regex. Tetapi biasanya Anda tertarik pada posisi pertandingan atau posisi subekspresi, dan Anda tidak bisa mendapatkannya dengan NSPredicate.
  2. Seperti yang disebutkan Anda dapat menggunakan fungsi regex POSIX . Tetapi mereka dianggap lambat, dan sintaks regex terbatas dibandingkan dengan solusi lain (ICU / pcre ).
  3. Ada banyak pustaka OSS, CocoaDev memiliki daftar lengkap .
  4. RegExKitLite misalnya tidak memerlukan pustaka, cukup tambahkan .m dan .h ke proyek Anda.

    (Keluhan saya terhadap RegExKitLite adalah bahwa ia memperluas NSString melalui kategori, tetapi juga dapat dianggap sebagai fitur. Juga menggunakan pustaka ICU nonpublik yang dikirim dengan OS, yang tidak direkomendasikan oleh Apple.)

mfazekas
sumber
3
Perlu diingat bahwa fungsi regex POSIX tidak berfungsi dengan unicode (ASCII saja).
Tom Dalling
FYI bahwa NSPredicate url adalah tautan rusak
taber
11
iOS mendukung ekspresi reguler untuk pencarian substring, misalnya[myString rangeOfString:@"regex_here" options:NSRegularExpressionSearch]
Nestor
1
Juga tersedia di Lion (10.7) #jika MAC_OS_X_VERSION_10_7 <= MAC_OS_X_VERSION_MAX_ALLOWED || __IPHONE_3_2 <= __IPHONE_OS_VERSION_MAX_ALLOWED
Maciej Swic
Saya merasa baik-baik saja untuk menggunakan perpustakaan ICU nonpublik, karena jika Anda perlu menggunakannya, itu karena tidak ada dukungan regex bawaan di versi Cocoa Anda. Jika Anda menggunakan perpustakaan itu, itu juga berarti bahwa Anda sedang membangun untuk sistem yang lebih lama, yang tidak akan lagi berubah karena tidak didukung. Jika Anda membangun untuk yang lama dan yang baru, Anda menggunakan RegExKitLite sebagai cadangan jika NSRegularExpression tidak ada. (Ya, masih ada orang yang bekerja pada sistem yang lebih tua).
19

RegexKit adalah yang terbaik yang saya temukan. Sangat Cocoa: y. Saya menggunakan versi "Lite" di beberapa aplikasi iPhone kami:

sourceforge

lingonikorg

alpukat
sumber
1
Saya kedua RegexKit Lite. Sangat bagus!
Dave Dribin
1
Keren, semakin banyak orang yang menggunakannya, mungkin akan semakin baik!
avocade
12

Anda dapat menggunakan pustaka POSIX Regular Expressions (Yay untuk OS yang mendukung POSIX). Mencoba

man 3 regex
Adam Wright
sumber
Oh begitu. ini adalah cara untuk melakukannya dalam C langsung, yang mungkin seharusnya bekerja di aplikasi objektif-C. keren Terimakasih! Apakah itu pada dasarnya cara yang diterima untuk melakukan ini?
Dreeves
Itu cara, yang tidak memerlukan dependensi tambahan. Ada pilihan lain, dalam hal pustaka sumber terbuka yang dapat Anda impor (PCRE, untuk regex Perl, pustaka Boost RegEx jika Anda menggunakan Obj-C ++, atau yang lain yang tercantum dalam jawaban lain).
Adam Wright
Adakah kerugian untuk mencampur C langsung dengan Objective-C? Bisakah Anda memasukkan cuplikan kode untuk mengonversi ke dan dari NSString? Terima kasih lagi!
Dreeves
Objective-C dibangun di atas C, jadi Anda tidak benar-benar mencampur apa pun. Sebagian besar orang menggunakan perpustakaan, karena ia menawarkan API yang lebih mudah digunakan.
Marc Charbonneau
5
Dan karena fungsi regex POSIX hanya berfungsi dengan string ASCII.
Tom Dalling
8

Solusi hack murah dan kotor yang saya gunakan untuk memecahkan masalah parsing REGEX dan JSON adalah membuat objek UIWebView dan menyuntikkan fungsi Javascript untuk melakukan parsing. Fungsi javascript kemudian mengembalikan string nilai (atau daftar nilai) yang saya pedulikan. Bahkan, Anda dapat menyimpan satu set fungsi perpustakaan kecil yang dikustomisasi untuk tugas-tugas tertentu dan kemudian memanggilnya sesuai kebutuhan.

Saya tidak tahu apakah ini teknik skala untuk volume besar permintaan parsing berulang, tetapi untuk hal transaksional cepat itu menyelesaikan pekerjaan tanpa tergantung pada sumber daya eksternal atau kode yang Anda mungkin tidak mengerti.

Mark Caufman
sumber
7

Saya suka kerangka AGRegex yang menggunakan PCRE, berguna jika Anda terbiasa dengan sintaks PCRE. Versi terbaik dari kerangka kerja ini adalah yang ada di klien IRC Colloquy karena telah ditingkatkan untuk menggunakan PCRE 6.7:

http://colloquy.info/project/browser/trunk/Frameworks/AGRegex

Ini sangat ringan, lebih dari RegExKit (walaupun tentu saja tidak mampu).

Rob Keniger
sumber
Mengapa kurang mampu jika memiliki regex perl-kompatibel penuh?
Dreeves
Metode pembantu Objective-C terkait hampir tidak seluas seperti yang ada di RegExKit, namun mereka baik-baik saja untuk sebagian besar tujuan.
Rob Keniger
6

NSRegularExpression tersedia sejak Mac OS X v10.7 dan iOS 4.0.

bbaassssiiee
sumber
5

Selama pencarian saya tentang topik ini saya menemukan CocoaOniguruma yang menggunakan Oniguruma , mesin Ekspresi Reguler di belakang Ruby1.9 dan PHP5. Tampaknya sedikit lebih baru dibandingkan dengan OregKit yang ada (dalam bahasa Jepang). Tidak yakin bagaimana ini menumpuk pada binding lainnya.

newtonapple
sumber
4

Googling alittle, menemukan perpustakaan ini: RegexOnNSString

Pustaka sumber terbuka, yang berisi fungsi-fungsi seperti:

-(NSString *) stringByReplacingRegexPattern:(NSString *)regex withString:(NSString *) replacement caseInsensitive:(BOOL)ignoreCase

dan menggunakan NSRegularExpressionkelas. Cukup mudah digunakan dan tidak perlu khawatir tentang apa pun.

Harap dicatat, NSRegularExpressiontersedia sejak Mac OS X v10.7 dan iOS 4.0, seperti yang disebutkan Datasmid.

nickeyzzz
sumber
1

Saya membuatnya mudah. Saya menambahkan file C ++ baru ke proyek Objective C saya, ganti namanya menjadi .mm, dan kemudian buat kelas C ++ standar di dalamnya. Kemudian, saya membuat metode kelas statis di bagian "publik:" untuk fungsi C ++ yang mengambil NSString dan mengembalikan NSString (atau NSArray, jika itu yang Anda inginkan). Saya kemudian mengonversi NSString ke C ++ std :: string seperti ini:

// If anyone knows a more efficient way, let me know in the comments.
// The "if" condition below is because ObjC crashes if converting to
// std::string if the string is nil or empty.
// assume #include <string>
std::string s = "";
if (([sInput != nil]) && (!([sInput isEqualTo:@""]))) {
  std::string sTemp([sInput UTF8String]);
  s = sTemp;
}

Dari sana, saya bisa menggunakan regex_replace seperti:

// assume #include <regex>
std::string sResult = std::regex_replace(sSource,sRegExp,sReplaceWith);

Lalu, saya bisa mengonversi std :: string itu kembali menjadi NSString dengan:

NSString *sResponse2 = @(sResult.c_str());

Jika Anda hanya menggunakan C ++ ini hanya untuk fungsi ini, maka Anda mungkin merasa cocok untuk memanggil file ini extra.mm (nama kelas Extra) dan memasukkan metode kelas statis ini, dan kemudian menambahkan metode kelas statis lainnya ketika situasi tiba di mana masuk akal untuk melakukannya di C ++ karena itu kurang merepotkan dalam beberapa kasus. (Ada beberapa kasus di mana ObjC melakukan sesuatu dengan lebih sedikit baris kode, dan beberapa kasus di mana C ++ melakukannya dengan lebih sedikit baris kode.)

PS Masih cara lain dengan ini adalah dengan menggunakan file .mm tetapi membuat pembungkus Objective C sekitar penggunaan std :: string dan std :: regex_replace () (atau regex_match ()).

Volomike
sumber