Biểu thức chính quy trong ứng dụng Cacao Objective-C


173

Googling ban đầu chỉ ra rằng không có cách tích hợp nào để thực hiện các biểu thức chính quy trong ứng dụng Cacao Objective-C.

Vì vậy, bốn câu hỏi:

  1. Điều đó có thực sự đúng không?

  2. Bạn đang đùa tôi à

  3. Ok, sau đó có một thư viện mã nguồn mở đẹp mà bạn đề xuất không?

  4. Các cách để có đủ gần mà không cần nhập thư viện, có lẽ với lớp NSScanner?


4
Hmmmm ... Tôi tự hỏi điều gì xảy ra nếu bạn sử dụng Monotouch. +1 cho câu hỏi.
Dan Rosenstark

Câu trả lời:



42
  1. Có, không có hỗ trợ regex trong ca cao. Nếu bạn chỉ quan tâm đến kết hợp boolean, bạn có thể sử dụng NSPredicate hỗ trợ cú pháp regex ICU. Nhưng thông thường, bạn quan tâm đến vị trí của trận đấu hoặc vị trí của các phần phụ và bạn không thể có được nó với NSPredicate.
  2. Như đã đề cập, bạn có thể sử dụng các hàm POSIX regex . Nhưng chúng được coi là chậm và cú pháp regex bị hạn chế so với các giải pháp khác (ICU / pcre ).
  3. Có rất nhiều thư viện OSS, CocoaDev có một danh sách rộng lớn .
  4. Ví dụ, RegExKitLite không yêu cầu bất kỳ thư viện nào, chỉ cần thêm .m và .h vào dự án của bạn.

    (Khiếu nại của tôi đối với RegExKitLite là nó mở rộng NSString thông qua danh mục, nhưng nó cũng có thể được coi là một tính năng.


3
Hãy nhớ rằng các hàm regex POSIX không hoạt động với unicode (chỉ ASCII).
Tom Dalling

FYI rằng url NSPredicate là một liên kết bị hỏng
taber

11
iOS hỗ trợ biểu thức thông thường cho các tìm kiếm substring, ví dụ:[myString rangeOfString:@"regex_here" options:NSRegularExpressionSearch]
Nestor

1
Cũng có sẵn trong 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

Tôi thấy sử dụng các thư viện ICU không công khai là tốt, bởi vì nếu bạn cần sử dụng nó, thì đó là vì không có hỗ trợ regex tích hợp trong phiên bản Ca cao của bạn. Nếu bạn sử dụng các thư viện đó, điều đó cũng có nghĩa là bạn đang xây dựng các hệ thống cũ hơn, sẽ không còn được thay đổi vì chúng không được hỗ trợ. Nếu bạn đang xây dựng cho cả cũ và mới, bạn sử dụng RegExKitLite làm dự phòng nếu NSRegularExpression không tồn tại. (Có, vẫn có người làm việc trên các hệ thống cũ).

19

RegexKit là sản phẩm tốt nhất tôi từng tìm thấy. Rất ca cao: y. Tôi đang sử dụng phiên bản "Lite" trong một số ứng dụng iPhone của chúng tôi:

nguồn

lingonikorg


1
Tôi thứ hai RegexKit Lite. Rất đẹp!
Dave Dribin

1
Thật tuyệt, càng nhiều người sử dụng nó, nó sẽ càng trở nên tốt hơn!
avocade

12

Bạn có thể sử dụng thư viện Biểu thức chính quy POSIX (Yay cho HĐH tuân thủ POSIX). Thử

man 3 regex

ồ, tôi hiểu rồi đây là một cách để làm điều đó trong C thẳng, có lẽ nên hoạt động trong bất kỳ ứng dụng C-object nào. tuyệt thật, cảm ơn nhé! về cơ bản đó là cách được chấp nhận để làm điều này?
dreeves

Đó là một cách, không yêu cầu bất kỳ phụ thuộc bổ sung. Có các lựa chọn khác, về các thư viện nguồn mở mà bạn có thể nhập (PCRE, cho các biểu thức Perl, thư viện Boost RegEx nếu bạn đang sử dụng Obj-C ++ hoặc các thư mục khác được liệt kê trong các câu trả lời khác).
Adam Wright

Bất kỳ nhược điểm nào khi trộn thẳng C với Objective-C? Bạn có thể bao gồm một đoạn mã để chuyển đổi sang và từ NSString không? cảm ơn lần nữa
dreeves

Objective-C được xây dựng trên đỉnh C, vì vậy bạn không thực sự trộn lẫn bất cứ thứ gì. Hầu hết mọi người sử dụng một thư viện, vì nó cung cấp một API dễ sử dụng hơn.
Marc Charbonneau

5
Và bởi vì các hàm regex POSIX chỉ hoạt động với các chuỗi ASCII.
Tom Dalling

8

Giải pháp hack rẻ và bẩn mà tôi sử dụng để giải quyết các vấn đề phân tích cú pháp REGEX và JSON là tạo một đối tượng UIWebView và tiêm (các) hàm Javascript để thực hiện phân tích cú pháp. Hàm javascript sau đó trả về một chuỗi giá trị (hoặc danh sách các giá trị) mà tôi quan tâm. Trong thực tế, bạn có thể lưu trữ một bộ thư viện nhỏ các chức năng được tùy chỉnh cho các tác vụ cụ thể và sau đó chỉ cần gọi chúng khi cần thiết.

Tôi không biết liệu kỹ thuật này có quy mô thành khối lượng lớn các yêu cầu phân tích lặp đi lặp lại hay không, nhưng đối với các công cụ giao dịch nhanh, nó sẽ hoàn thành công việc mà không phụ thuộc vào bất kỳ tài nguyên bên ngoài hoặc mã nào bạn có thể không hiểu.


7

Tôi thích khung AGRegex sử dụng PCRE, tiện dụng nếu bạn đã quen với cú pháp PCRE. Phiên bản tốt nhất của khung này là phiên bản trong ứng dụng khách Colloquy IRC vì nó đã được nâng cấp để sử dụng PCRE 6.7:

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

Nó rất nhẹ, hơn rất nhiều so với RegExKit (mặc dù tất nhiên là không có khả năng).


Tại sao ít khả năng hơn nếu nó có regex tương thích đầy đủ perl?
dreeves

Các phương thức của trình trợ giúp Objective-C có liên quan gần như không rộng như các phương thức trong RegExKit, tuy nhiên chúng vẫn ổn cho hầu hết các mục đích.
Rob Keniger


5

Trong quá trình tìm kiếm của tôi về chủ đề này, tôi đã bắt gặp CocoaOniguruma sử dụng Oniguruma , công cụ Biểu thức chính quy đằng sau Ruby1.9 và PHP5. Có vẻ như mới hơn một chút so với OregKit hiện có (bằng tiếng Nhật). Không chắc chắn làm thế nào những chồng này chống lại các ràng buộc khác.


4

Googling alittle, tìm thấy thư viện này: RegexOnNSString

Thư viện mã nguồn mở, chứa các hàm như:

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

và sử dụng NSRegularExpressionlớp học. Khá dễ sử dụng và không cần phải lo lắng về bất cứ điều gì.

Xin lưu ý rằng NSRegularExpressioncó sẵn từ Mac OS X v10.7 và IOS 4.0, như Datasmid đã đề cập.


1

Tôi làm cho nó dễ dàng. Tôi thêm một tệp C ++ mới vào dự án Objective C của mình, đổi tên nó thành .mm, sau đó tạo một lớp C ++ tiêu chuẩn bên trong. Sau đó, tôi tạo một phương thức lớp tĩnh trong phần "công khai:" cho hàm C ++ có NSString và trả về NSString (hoặc NSArray, nếu đó là điều bạn muốn). Sau đó tôi chuyển đổi NSString sang C ++ std :: string như vậy:

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

Từ đó, tôi có thể sử dụng regex numplace như vậy:

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

Sau đó, tôi có thể chuyển chuỗi std :: đó thành NSString với:

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

Nếu bạn chỉ sử dụng C ++ này cho chức năng này, thì bạn có thể thấy nó phù hợp để gọi tệp này thêm.mm (tên lớp Extra) và đặt phương thức lớp tĩnh này vào, sau đó thêm các phương thức lớp tĩnh khác khi tình huống đến trong đó có ý nghĩa để làm điều đó trong C ++ vì nó ít rắc rối hơn trong một số trường hợp. (Có những trường hợp ObjC làm một cái gì đó với ít dòng mã hơn và một số trường hợp C ++ thực hiện nó với ít dòng mã hơn.)

PS Vẫn còn một cách khác với điều này là sử dụng tệp .mm nhưng tạo một trình bao bọc Objective C xung quanh việc sử dụng std :: string và std :: regex numplace () (hoặc regex_match ()).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.