Objective-C Kakao uygulamasında düzenli ifadeler


173

İlk Google, Objective-C Kakao uygulamasında düzenli ifadeler yapmanın yerleşik bir yolu olmadığını gösterir.

Yani dört soru:

  1. Bu gerçekten doğru mu?

  2. Benimle dalga mı geçiyorsun?

  3. Tamam, o zaman tavsiye ettiğin güzel bir açık kaynaklı kütüphane var mı?

  4. Belki NSScanner sınıfıyla bir kitaplığı içe aktarmadan yeterince yakınlaşmanın yolları nelerdir?


4
Hmmmm ... Monotouch kullanırsan ne olacağını merak ediyorum. Soru için +1.
Dan Rosenstark

Yanıtlar:



42
  1. Evet, Kakao'da normal ifade desteği yok. Yalnızca boole eşleşmesiyle ilgileniyorsanız , ICU normal ifade sözdizimini destekleyen NSPredicate'i kullanabilirsiniz . Ancak genellikle eşleşmenin konumu veya alt ifadelerin konumu ile ilgilenirsiniz ve NSPredicate ile elde edemezsiniz.
  2. Belirtildiği gibi normal ifade POSIX işlevlerini kullanabilirsiniz . Ancak yavaş olarak kabul edilirler ve normal ifade sözdizimi diğer çözümlere (ICU / pcre ) kıyasla sınırlıdır .
  3. Çok sayıda OSS kütüphanesi var, CocoaDev'in kapsamlı bir listesi var .
  4. Örneğin, RegExKitLite herhangi bir kütüphane gerektirmez, sadece projenize .m ve .h ekleyin.

    (RegExKitLite'a karşı şikayetim, NSString'i kategori yoluyla genişletmesidir, ancak bir özellik olarak da kabul edilebilir.


3
POSIX normal ifade işlevlerinin unicode ile çalışmadığını unutmayın (yalnızca ASCII).
Tom Dalling

NSPredicate url'si bozuk bir bağlantıdır
taber

11
iOS, alt dize aramaları için düzenli ifadeleri destekler, örneğin[myString rangeOfString:@"regex_here" options:NSRegularExpressionSearch]
Nestor

1
Ayrıca Lion (10.7) #if MAC_OS_X_VERSION_10_7 <= MAC_OS_X_VERSION_MAX_ALLOWED || __IPHONE_3_2 <= __IPHONE_OS_VERSION_MAX_ALLOWED
Maciej Swic

Halka açık olmayan YBÜ kütüphanelerini kullanmanın iyi olduğunu düşünüyorum, çünkü kullanmanız gerekiyorsa, bunun nedeni Cocoa sürümünüzde yerleşik bir normal regex desteği olmamasıdır. Bu kütüphaneleri kullanırsanız, desteklenmediği için artık değiştirilmeyecek olan eski sistemler için de inşa ettiğiniz anlamına gelir. Hem eski hem de yeni için oluşturuyorsanız, NSRegularExpression yoksa RegExKitLite'ı yedek olarak kullanırsınız. (Evet, hala eski sistemlerde çalışan insanlar var).

19

RegexKit henüz bulduğum en iyisi. Çok Kakao: y. İPhone uygulamalarımızın birçoğunda "Lite" sürümünü kullanıyorum:

sourceforge

lingonikorg


1
Ben ikinci RegexKit Lite. Çok hoş!
Dave Dribin

1
Güzel, ne kadar çok insan kullanırsa, muhtemelen o kadar iyi olacak!
avokade

12

POSIX Düzenli İfadeler kitaplığını kullanabilirsiniz (POSIX uyumlu bir işletim sistemi için Yay). Deneyin

man 3 regex

Ah anlıyorum. Bu, muhtemelen herhangi bir objektif C uygulamasında çalışması gereken düz C'de yapmanın bir yoludur. havalı, teşekkürler! temelde bunu yapmanın kabul edilen yolu mu?
dreeves

Bu, herhangi bir ek bağımlılık gerektirmeyen bir yoldur. Açık kaynak kitaplıkları alabileceğiniz başka seçenekler de vardır (PCRE, Perl regexes için, Obj-C ++ kullanıyorsanız Boost RegEx kitaplığı veya diğer yanıtlarda listelenen diğerleri).
Adam Wright

Objektif C ile düz C'yi karıştırmanın herhangi bir dezavantajı var mı? NSString'e ve NSString'den dönüştürmek için bir kod snippet'i ekleyebilir misiniz? Tekrar teşekkürler!
dreeves

Objective-C, C'nin üzerine inşa edilmiştir, bu yüzden gerçekten hiçbir şeyi karıştırmazsınız. Çoğu kişi, kullanımı kolay bir API sunduğu için bir kütüphane kullanır.
Marc Charbonneau

5
POSIX normal ifadesi işlevleri yalnızca ASCII dizeleriyle çalıştığı için.
Tom Dalling

8

REGEX ve JSON ayrıştırma sorunlarını çözmek için kullandığım ucuz ve kirli kesmek çözüm bir UIWebView nesnesi oluşturmak ve ayrıştırma yapmak için Javascript işlev (ler) enjekte etmektir. Javascript işlevi daha sonra umurumda değer (veya değer listesi) bir dize döndürür. Aslında, belirli görevler için özelleştirilmiş küçük bir kütüphane işlevi kümesini saklayabilir ve sonra bunları gerektiği gibi çağırabilirsiniz.

Bu tekniğin büyük miktarlarda tekrarlanan ayrıştırma isteklerine ölçeklenip ölçeklenmediğini bilmiyorum, ancak hızlı işlem şeyler için, anlayamayacağınız herhangi bir ekstra dış kaynağa veya koda bağlı olmadan işi hallediyor.


7

PCRE sözdizimine alışkınsanız, PCRE kullanan AGRegex çerçevesini seviyorum. Bu çerçevenin en iyi sürümü, PCRE 6.7 kullanacak şekilde yükseltildiği için Colloquy IRC istemcisindeki sürümdür:

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

Çok hafif, RegExKit'ten çok daha fazla (tabii ki yetenekli olmasa da).


Tam perl uyumlu regex'e sahipse neden daha az yetenekli?
08

İlişkili Objective-C yardımcı yöntemleri neredeyse RegExKit'tekiler kadar kapsamlı değildir, ancak çoğu amaç için uygundur.
Rob Keniger


5

Bu konuyla ilgili benim arama sırasında ben rastladım CocoaOniguruma kullanan Oniguruma , Ruby1.9 ve PHP5 arkasında Normal İfade motorunu. Mevcut OregKit'e (Japonca) kıyasla biraz daha yeni görünüyor . Bunların diğer ciltlere nasıl yığıldığından emin değilim.


4

Alogling alittle, şu kütüphaneyi buldu: RegexOnNSString

Aşağıdaki gibi işlevleri içeren açık kaynak kitaplığı:

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

ve NSRegularExpressionsınıf kullanma . Kullanımı oldukça kolaydır ve hiçbir şey için endişelenmenize gerek yoktur.

NSRegularExpressionDatasmid'in belirttiği gibi Mac OS X v10.7 ve IOS 4.0'dan beri mevcut olduğunu lütfen unutmayın .


1

Kolaylaştırıyorum. Objective C projeme yeni bir C ++ dosyası ekleyin, .mm olarak yeniden adlandırın ve sonra içinde standart bir C ++ sınıfı oluşturun. Sonra, bir NSString alır ve bir NSString (veya NSArray, isterseniz budur) döndüren bir C ++ işlevi için "public:" bölümünde statik bir sınıf yöntemi yapmak. Sonra C ++ std :: string NSString dönüştürmek gibi:

// 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;
}

Oradan, böyle regex_replace kullanabilirsiniz:

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

Sonra, bu std :: string ile bir NSString dönüştürebilirsiniz:

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

Bu C ++ 'ı yalnızca bu işlev için kullanıyorsanız, bu dosyayı extra.mm (sınıf adı Ekstra) olarak adlandırmayı ve bu statik sınıf yöntemini koymayı ve durum geldiğinde diğer statik sınıf yöntemlerini eklemeyi uygun bulabilirsiniz. C ++ 'da bunu yapmak mantıklıdır çünkü bazı durumlarda daha az güçlük çeker. (ObjC'nin daha az kod satırıyla bir şeyler yaptığı durumlar ve C ++ 'nın daha az kod satırıyla yaptığı durumlar vardır.)

PS Bununla birlikte yine başka bir yol .mm dosyası kullanmak ancak std :: string ve std :: regex_replace () (veya regex_match ()) kullanımı etrafında bir Objective C sarıcı yapmaktır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.