นิพจน์ทั่วไปในแอปพลิเคชัน Objective-C Cocoa


173

Googling เริ่มต้นบ่งชี้ว่าไม่มีวิธีในการทำนิพจน์ปกติในแอปพลิเคชัน Objective-C Cocoa

ดังนั้นสี่คำถาม:

  1. เป็นเรื่องจริงเหรอ?

  2. คุณล้อเล่นกับฉันไหม

  3. ตกลงแล้วมีไลบรารีโอเพนซอร์ซดีๆที่คุณแนะนำไหม

  4. มีวิธีใดบ้างที่จะเข้าใกล้พอโดยไม่ต้องนำเข้าห้องสมุดบางทีอาจใช้คลาส NSScanner


4
อืม ... ฉันสงสัยว่าจะเกิดอะไรขึ้นถ้าคุณใช้ Monotouch +1 สำหรับคำถาม
Dan Rosenstark

คำตอบ:



42
  1. ใช่ไม่มีการสนับสนุน regex ใน Cocoa หากคุณสนใจในการจับคู่บูลีนเท่านั้นคุณสามารถใช้NSPredicateซึ่งรองรับไวยากรณ์ ICU regex แต่โดยปกติคุณจะสนใจตำแหน่งการจับคู่หรือตำแหน่งของนิพจน์ย่อยและคุณไม่สามารถรับมันด้วย NSPredicate
  2. เป็นที่กล่าวถึงคุณสามารถใช้ฟังก์ชั่น POSIX regex แต่ก็ถือว่าช้าและไวยากรณ์ regex นั้นมี จำกัด เมื่อเปรียบเทียบกับโซลูชันอื่น (ICU / pcre )
  3. มีห้องสมุด OSS มากมายCocoaDev มีรายการมากมาย
  4. ตัวอย่างRegExKitLiteไม่ต้องการไลบรารีใด ๆ เพียงเพิ่ม. m และ. h เข้ากับโครงการของคุณ

    (การร้องเรียนของฉันต่อ RegExKitLite คือมันขยาย NSString ผ่านหมวดหมู่ แต่ก็ถือได้ว่าเป็นคุณสมบัติเช่นกันนอกจากนี้ยังใช้ไลบรารี่ ICU ที่ไม่ใช่แบบสาธารณะที่ส่งมาพร้อมกับระบบปฏิบัติการซึ่งไม่ได้แนะนำโดย Apple)


3
โปรดทราบว่าฟังก์ชั่น POSIX regex ไม่ทำงานกับ unicode (ASCII เท่านั้น)
Tom Dalling

FYI ที่ URL NSPredicate เป็นลิงก์ที่ขาด
taber

11
iOS รองรับนิพจน์ทั่วไปสำหรับการค้นหาสตริงย่อยเช่น[myString rangeOfString:@"regex_here" options:NSRegularExpressionSearch]
Nestor

1
มีให้ใน 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

ฉันคิดว่ามันดีที่จะใช้ไลบรารี่ ICU ที่ไม่ใช่สาธารณะเพราะถ้าคุณต้องการใช้มันอาจเป็นเพราะไม่มีการสนับสนุน regex ในตัวใน Cocoa เวอร์ชันของคุณ หากคุณใช้ไลบรารีเหล่านี้ก็หมายความว่าคุณกำลังสร้างระบบเก่าซึ่งจะไม่เปลี่ยนแปลงอีกต่อไปเนื่องจากไม่ได้รับการสนับสนุน หากคุณกำลังสร้างทั้งเก่าและใหม่คุณใช้ RegExKitLite เป็นทางเลือกหาก NSRegularExpression ไม่มีอยู่ (ใช่ยังมีคนที่ทำงานกับระบบเก่ากว่า)

19

RegexKit ดีที่สุดที่ฉันเคยพบมา โกโก้มาก: y ฉันกำลังใช้รุ่น "Lite" ในแอพ iPhone ของเราหลายแห่ง:

SourceForge

lingonikorg


1
ฉันสอง RegexKit Lite ดีมาก!
เดฟ Dribin

1
ยิ่งมีคนใช้มากเท่าไหร่ก็ยิ่งดีเท่านั้น!
avocade

12

คุณสามารถใช้ไลบรารี POSIX Regular Expressions (Yay สำหรับระบบปฏิบัติการที่สอดคล้องกับ POSIX) ลอง

man 3 regex

อ้อเข้าใจแล้ว. นี่เป็นวิธีที่จะทำในแบบตรงไปตรงมาซึ่งน่าจะทำงานในแอพ C-Object ใด ๆ เจ๋งขอบคุณ! นั่นเป็นวิธีที่ยอมรับกันโดยทั่วไปในการทำเช่นนี้หรือไม่?
2552

เป็นวิธีที่ไม่ต้องการการพึ่งพาเพิ่มเติมใด ๆ มีตัวเลือกอื่น ๆ ในแง่ของไลบรารีโอเพ่นซอร์สที่คุณสามารถนำเข้า (PCRE, สำหรับ Perl regexes, ห้องสมุด Boost RegEx ถ้าคุณใช้ Obj-C ++, หรืออื่น ๆ ที่อยู่ในคำตอบอื่น ๆ )
Adam Wright

ข้อเสียใด ๆ ในการผสม C ตรงกับ Objective-C? คุณสามารถรวมข้อมูลโค้ดสำหรับการแปลงจาก NSString ได้ไหม ขอบคุณอีกครั้ง!
2552

Objective-C สร้างขึ้นบน C ดังนั้นคุณไม่ได้ผสมอะไรเลย คนส่วนใหญ่ใช้ห้องสมุดเพราะมันมี API ที่ใช้งานง่ายกว่า
Marc Charbonneau

5
และเนื่องจากฟังก์ชัน POSIX regex จะทำงานกับสตริง ASCII เท่านั้น
Tom Dalling

8

วิธีแฮ็คราคาถูกและสกปรกที่ฉันใช้เพื่อแก้ปัญหาการแจง REGEX และ JSON คือการสร้างวัตถุ UIWebView และฉีดฟังก์ชัน Javascript เพื่อแยกวิเคราะห์ จากนั้นฟังก์ชั่นจาวาสคริปต์จะส่งคืนสตริงของค่า (หรือรายการค่า) ที่ฉันสนใจ ในความเป็นจริงคุณสามารถเก็บชุดไลบรารีขนาดเล็กของฟังก์ชั่นที่ปรับแต่งสำหรับงานเฉพาะแล้วเรียกพวกเขาได้ตามต้องการ

ฉันไม่รู้ว่าเทคนิคนี้จะขยายไปยังคำขอการแยกวิเคราะห์ซ้ำจำนวนมากหรือเปล่า แต่สำหรับการทำธุรกรรมที่รวดเร็วนั้นจะทำให้งานเสร็จโดยไม่ต้องพึ่งพาทรัพยากรภายนอกหรือรหัสเพิ่มเติมใด ๆ ที่คุณอาจไม่เข้าใจ


7

ฉันชอบกรอบ AGRegex ซึ่งใช้ PCRE ซึ่งมีประโยชน์ถ้าคุณคุ้นเคยกับไวยากรณ์ PCRE เวอร์ชันที่ดีที่สุดของเฟรมเวิร์กนี้คือหนึ่งในไคลเอนต์ IRC Colloquy เนื่องจากได้รับการอัพเกรดให้ใช้ PCRE 6.7:

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

มันมีน้ำหนักเบามากมากกว่า RegExKit (ถึงแม้จะไม่สามารถแน่นอน)


ทำไมจึงมีความสามารถน้อยลงถ้ามี regex ที่เข้ากันได้กับ Perl อย่างสมบูรณ์
# # # dreeves

วิธีการที่ผู้ช่วย Objective-C ที่เกี่ยวข้องนั้นไม่ได้มีความครอบคลุมเกือบเท่าวิธีการใน RegExKit แต่ก็ใช้ได้ดีกับวัตถุประสงค์ส่วนใหญ่
Rob Keniger


5

ในระหว่างการค้นหาของฉันในหัวข้อนี้ฉันเจอCocoaOnigurumaซึ่งใช้Onigurumaเครื่องมือ Expression ปกติที่อยู่เบื้องหลัง Ruby1.9 และ PHP5 ดูเหมือนว่าจะค่อนข้างใหม่กว่าเมื่อเทียบกับOregKit (ภาษาญี่ปุ่น) ที่มีอยู่ ไม่แน่ใจว่าสแต็คเหล่านี้เทียบกับการผูกอื่น ๆ


4

Googling alittle พบไลบรารีนี้: RegexOnNSString

ห้องสมุดโอเพ่นซอร์สที่มีฟังก์ชั่นเช่น:

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

และใช้NSRegularExpressionคลาส ใช้งานง่ายมากและไม่ต้องกังวลอะไร

โปรดทราบว่าNSRegularExpressionมีให้ตั้งแต่ Mac OS X v10.7 และ IOS 4.0 ตามที่ระบุไว้ใน Datasmid


1

ฉันทำให้มันง่าย ฉันเพิ่มไฟล์ C ++ ใหม่ลงในโครงการ Objective C ของฉันเปลี่ยนชื่อเป็น. mm แล้วสร้างคลาส C ++ มาตรฐานภายใน จากนั้นฉันสร้างเมธอดคลาสแบบสแตติกในส่วน "สาธารณะ:" สำหรับฟังก์ชัน C ++ ที่รับ NSString และส่งคืน NSString (หรือ NSArray หากนั่นคือสิ่งที่คุณต้องการ) ฉันจะแปลง NSString เป็น C ++ std :: string ดังนี้:

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

จากที่นั่นฉันสามารถใช้ regex_replace เช่นนั้น:

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

จากนั้นฉันสามารถแปลง std :: string กลับเป็น NSString ด้วย:

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

หากคุณเพียงแค่ใช้ C ++ สำหรับฟังก์ชั่นนี้เท่านั้นคุณอาจจะเรียกไฟล์นี้ว่า Extra.mm (ชื่อคลาส Extra) แล้วใส่เมธอดคลาสสแตติกนี้แล้วเพิ่มเมธอดคลาสสแตติกอื่นเมื่อสถานการณ์มาถึง ที่มันเหมาะสมที่จะทำมันใน C ++ เพราะมันมีความยุ่งยากน้อยกว่าในบางกรณี (มีบางกรณีที่ ObjC ทำบางสิ่งบางอย่างที่มีโค้ดน้อยกว่าและบางกรณีที่ C ++ ทำด้วยโค้ดน้อยกว่า)

PS ยังเป็นอีกวิธีหนึ่งในการทำเช่นนี้คือการใช้ไฟล์. mm แต่สร้าง wrapper ของ Objective C โดยใช้ std :: string และ std :: regex_replace () (หรือ regex_match ())

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.