Objective-C Cocoa 응용 프로그램의 정규식


173

초기 인터넷 검색은 Objective-C Cocoa 애플리케이션에서 정규 표현식을 수행 할 수있는 기본 제공 방법이 없음을 나타냅니다.

따라서 네 가지 질문이 있습니다.

  1. 정말 맞습니까?

  2. 농담 해?

  3. 그렇다면 추천 할만한 훌륭한 오픈 소스 라이브러리가 있습니까?

  4. NSScanner 클래스를 사용하여 라이브러리를 가져 오지 않고 충분히 가까워지는 방법은 무엇입니까?


4
흠 ... Monotouch를 사용하면 어떻게 될지 궁금합니다. 질문에 +1
— Dan Rosenstark

답변:



42
  1. 예, 코코아에서는 정규식 지원이 없습니다. 부울 일치에만 관심이있는 경우 ICU 정규식 구문을 지원 하는 NSPredicate 를 사용할 수 있습니다 . 그러나 일반적으로 하위 표현식의 일치 또는 위치에 관심이 있으며 NSPredicate를 사용하여 얻을 수 없습니다.
  2. 언급했듯이 정규식 POSIX 함수를 사용할 수 있습니다 . 그러나 그것들은 느리게 간주되며 정규 표현식 구문은 다른 솔루션 (ICU / pcre )에 비해 제한 됩니다.
  3. 많은 OSS 라이브러리가 있으며 CocoaDev는 광범위한 목록을 가지고 있습니다.
  4. 예를 들어 RegExKitLite 에는 라이브러리가 필요하지 않습니다. 프로젝트에 .m 및 .h를 추가하십시오.

    (RegExKitLite에 대한 불만은 카테고리를 통해 NSString을 확장하지만 기능으로 간주 될 수 있다는 것입니다. 또한 OS와 함께 제공되는 비공개 ICU 라이브러리를 사용하며 Apple에서 권장하지 않습니다.)


3
POSIX 정규식 함수는 유니 코드 (ASCII 만 해당)와 함께 작동하지 않습니다.
— Tom Dalling

참고로 NSPredicate URL은 끊어진 링크입니다
— 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 라이브러리를 사용하는 것이 좋습니다. 코코아 버전에는 정규식 지원 기능이 없기 때문에 사용해야합니다. 해당 라이브러리를 사용하는 경우 이전 시스템을 위해 빌드한다는 의미이기도합니다. 더 이상 지원되지 않으므로 변경되지 않습니다. NSRegularExpression이 존재하지 않는 경우 기존 및 신규를 위해 빌드하는 경우 RegExKitLite를 대체로 사용합니다. (예, 여전히 오래된 시스템을 사용하는 사람들이 있습니다).

19

RegexKit은 내가 찾은 최고입니다. 매우 코코아 : y. 여러 iPhone 앱에서 "Lite"버전을 사용하고 있습니다.

소스 포지

Lingonikorg


1
두 번째 RegexKit Lite입니다. 아주 좋아요!
— Dave Dribin

1
차갑고, 사람들이 많을수록 더 좋아질 것입니다!
— avocade

12

POSIX 정규식 라이브러리를 사용할 수 있습니다 (POSIX 호환 OS의 경우 예). 시험

man 3 regex

아, 알 겠어요 이것은 똑바로 C 로하는 방법이며, 아마도 objective-C 앱에서 작동해야합니다. 멋지다, 고마워! 이것이 기본적으로 허용되는 방법입니까?
— dreeves

추가 종속성이 필요하지 않은 방법입니다. 가져올 수있는 오픈 소스 라이브러리와 관련하여 다른 선택 사항이 있습니다 (PCRE, Perl regexe의 경우 Boost RegEx 라이브러리 또는 Obj-C ++를 사용하는 경우 Boost RegEx 라이브러리 또는 다른 답변에 나열된 항목).
— Adam Wright

스트레이트 C와 Objective-C를 혼합하는 데 어떤 단점이 있습니까? NSString과의 변환을위한 코드 스 니펫을 포함시킬 수 있습니까? 다시 감사합니다!
— Dreeves

Objective-C는 C를 기반으로하므로 실제로 어떤 것도 혼합하지 않습니다. 그러나 대부분의 사람들은 사용하기 쉬운 API를 제공하기 때문에 라이브러리를 사용합니다.
— Marc Charbonneau

5
POSIX 정규식 함수는 ASCII 문자열에서만 작동합니다.
— Tom Dalling

8

REGEX 및 JSON 파싱 문제를 해결하는 데 사용하는 저렴하고 더러운 해킹 솔루션은 UIWebView 객체를 만들고 파싱을 수행하기 위해 Javascript 함수를 주입하는 것입니다. 그런 다음 javascript 함수는 내가 관심있는 값 (또는 값 목록)의 문자열을 반환합니다. 실제로 특정 작업에 맞게 사용자 정의 된 작은 라이브러리 함수를 저장 한 다음 필요에 따라 호출 할 수 있습니다.

이 기술이 엄청난 양의 반복되는 구문 분석 요청으로 확장되는지는 모르겠지만 빠른 트랜잭션 작업을 위해 이해할 수없는 추가 외부 리소스 또는 코드에 의존하지 않고 작업을 수행합니다.


7

PCRE를 사용하는 AGRegex 프레임 워크가 마음에 들어 PCRE 구문에 익숙하다면 편리합니다. 이 프레임 워크의 최고 버전은 PCRE 6.7을 사용하도록 업그레이드 된 Colloquy IRC 클라이언트의 프레임 워크입니다.

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

RegExKit보다 훨씬 가볍습니다 (물론 가능하지는 않지만).


완전한 펄 호환 정규식을 가지고 있다면 왜 능력이 떨어 집니까?
— Dreeves

관련된 Objective-C 도우미 메서드는 RegExKit의 메서드만큼 광범위하지는 않지만 대부분의 목적에 적합합니다.
— Rob Keniger

6

NSRegularExpression Mac OS X v10.7 및 IOS 4.0부터 사용할 수 있습니다.


5

이 주제를 검색하는 동안 Ruby1.9 및 PHP5의 정규 표현식 엔진 인 Oniguruma 를 사용하는 CocoaOniguruma 를 발견했습니다. 기존의 OregKit (일본어)에 비해 조금 더 새로운 것 같습니다 . 이것들이 다른 바인딩과 어떻게 겹쳐 지는지 확실하지 않습니다.


4

인터넷 검색이 조금 쉬워 RegexOnNSString 라이브러리를 찾았 습니다.

다음과 같은 기능을 포함하는 오픈 소스 라이브러리 :

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

그리고 NSRegularExpression수업을 사용 합니다. 사용하기 쉽고 아무것도 걱정할 필요가 없습니다.

, 유의하시기 바랍니다 NSRegularExpressionDatasmid가 언급 한 바와 같이, 맥 OS X의 v10.7 및 IOS 4.0부터 사용할 수 있습니다.


1

나는 그것을 쉽게 만든다. Objective C 프로젝트에 새 C ++ 파일을 추가하고 이름을 .mm로 바꾼 다음 표준 C ++ 클래스를 작성합니다. 그런 다음 NSString을 사용하고 NSString (또는 원하는 경우 NSArray)을 반환하는 C ++ 함수에 대해 "public :"섹션에서 정적 클래스 메서드를 만듭니다. 그런 다음 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 ++가 더 적은 코드 줄로 그것을하는 경우가 있습니다.)

추신 : 이것의 또 다른 방법은 .mm 파일을 사용하지만 std :: string 및 std :: regex_replace () (또는 regex_match ()) 사용 주위에 Objective C 래퍼를 만드는 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.