Objective-C Cocoa应用程序中的正则expression式
初始Googlesearch表明在Objective-C Cocoa应用程序中没有内置的方法来执行正则expression式。
所以有四个问题:
-
这是真的吗?
-
你在跟我开玩笑吗?
-
好的,那么你有一个很好的开源库吗?
-
有什么办法可以在不导入图书馆的情况下使用NSScanner类来实现?
我注意到,从iOS 4.0开始,Apple提供了一个NSRegularExpression类 。 此外,从10.7开始,该类在OS X下可用。
- 是的,Cocoa没有正则expression式的支持。 如果您只对布尔匹配感兴趣,则可以使用支持ICU正则expression式语法的NSPredicate 。 但通常情况下,您对子expression式的匹配或位置感兴趣,而您无法使用NSPredicate获取它。
- 如上所述,您可以使用正则expression式POSIX函数 。 但是它们被认为是慢的,与其他解决scheme(ICU / pcre )相比,正则expression式的语法是有限的。
- 有许多OSS库, CocoaDev有一个广泛的列表 。
-
例如RegExKitLite不需要任何库,只需将.m和.h添加到您的项目。
(我对RegExKitLite的投诉是它通过类别扩展了NSString,但它也可以被认为是一个function,它也使用了OS附带的非公开的ICU库,这是Apple不推荐的)。
RegexKit是我find的最好的。 非常cocoa:y。 我在几个iPhone应用程序中使用“Lite”版本:
SourceForge上
lingonikorg
您可以使用POSIX正则expression式库(适用于符合POSIX标准的OS)。 尝试
man 3 regex
我用来解决REGEX和JSONparsing问题的廉价和肮脏的黑客解决scheme是创build一个UIWebView对象,并注入Javascript函数来parsing。 然后javascript函数返回一个我关心的值(或值列表)的string。 实际上,您可以存储一个小型库函数,为特定任务定制,然后根据需要调用它们。
我不知道这个技术是否可以扩展到大量重复的parsing请求,但是对于快速的事务处理来说,它可以完成工作,而不依赖于任何额外的外部资源或者你可能不了解的代码。
我喜欢使用PCRE的AGRegex框架,如果您习惯于PCRE语法,那么就很方便。 这个框架的最佳版本是Colloquy IRC客户端的版本,因为它已经升级到使用PCRE 6.7:
http://colloquy.info/project/browser/trunk/Frameworks/AGRegex
这是非常轻量级的,比RegExKit更重要(虽然当然不是)。
从Mac OS X v10.7和IOS 4.0开始, NSRegularExpression
就可以使用了。
在我search这个主题的过程中,我遇到了CocoaOniguruma ,它使用Oniguruma ,这是Ruby1.9和PHP5背后的正则expression式引擎。 与现有的OregKit (日文)相比,它似乎有点新。 不知道如何堆叠对其他绑定。
谷歌searchalittle,发现这个库: RegexOnNSString
开源库,包含如下function:
-(NSString *) stringByReplacingRegexPattern:(NSString *)regex withString:(NSString *) replacement caseInsensitive:(BOOL)ignoreCase
并使用NSRegularExpression
类。 很容易使用,无需担心任何事情。
请注意NSRegularExpression
自Mac OS X v10.7和IOS 4.0开始可用,如Datasmid所述。
我很容易。 我将一个新的C ++文件添加到我的Objective C项目中,重命名为.mm,然后在里面创build一个标准的C ++类。 然后,我在一个C ++函数的“public:”部分中创build一个静态类方法,该函数接受一个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 ++来实现这个function,那么你可能会觉得适合调用这个文件extra.mm(类名Extra),并把这个静态类方法放进去,然后在情况到来时添加其他静态类方法在C ++中使用它是有道理的,因为在某些情况下它不那么麻烦。 (有些情况下,ObjC使用更less的代码行来处理某些事情,有些情况下C ++使用更less的代码行。
PS还有另一种方法是使用.mm文件,但是使用std :: string和std :: regex_replace()(或regex_match())来制作一个Objective C包装器。