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.