我真的很想把regexkit(或我自己的libpcre包装器)放到我的项目中,这样做,但在我这样做之前,我想知道cocoa开发人员如何在没有真正复杂的代码或没有与regexkit或另一个正则表达式库链接的情况下完成这一半基本工作。
我觉得可可不包括
任何
正则表达式匹配功能。我已经习惯了用正则表达式来处理各种事情,没有它们我就迷失了方向。如果没有它们,我可以做我需要的事情,但是代码相当复杂。所以,可可开发人员,我问你,“可可方法”是什么?
就我而言,这个问题是编程中的一个日常问题。Cocoa必须通过内置功能来实现这一点。请注意,我想要匹配更改的元素的位置,有时会出现“引号”。空白是可变的。
使用以下字符串:
Content-Type: application/xml; charset=utf-8
Content-Type: text/html; charset="iso-8859-1"
Content-Type: text/plain;
charset=us-ascii
Content-Type: text/plain; name="example.txt"; charset=utf-8
从所有这些字符串中,您将如何使用内置的cocoa类来确定mime类型(例如,text/plain)和字符集(例如,utf-8)?
最后我会表演一系列
-rangeOfString:
以及子字符串调用,以及处理可选引号的条件检查等。是否有一种方法可以使用nsscanner进行此操作?nsscanner类对我来说似乎有一个相当幼稚的API。
有点像C
sscanf()
对于nsstring对象来说,这是一个理想的匹配。我的大多数字符串解析需求都很简单,比如这个例子,所以当我习惯了正则表达式的时候,它们可能是多余的?
edit代码有点冗长,但事实证明nsscanner实际上很容易使用。它基本上是沿着你的线走的,就像你说的那样。最烦人的部分是
NSCharacterSet
它需要的实例。
- (void)testNSScannerUseCase {
NSString *testString = @"Content-type: application/xml; name=\"test\";\n charset=\"utf-8\"";
unsigned int a = 'a', zero = '0';
// There's probably a quicker way than to make these character sets this way
NSMutableCharacterSet *alphaNumSet = [NSMutableCharacterSet characterSetWithRange:NSMakeRange(a, 26)];
[alphaNumSet addCharactersInRange:NSMakeRange(zero, 10)];
NSMutableCharacterSet *mimeTypeSet = [NSMutableCharacterSet characterSetWithCharactersInString:@"/-"];
[mimeTypeSet formUnionWithCharacterSet:alphaNumSet];
NSMutableCharacterSet *charsetSet = [NSMutableCharacterSet characterSetWithCharactersInString:@"-"];
[charsetSet formUnionWithCharacterSet:alphaNumSet];
// Initialize a case-insensitive scanner
NSScanner *scanner = [NSScanner scannerWithString:testString];
[scanner setCaseSensitive:NO];
// Prepare to capture mime-type
NSString *mimeType = nil;
// Skip past the Content-Type: section
if ([scanner scanUpToString:@":" intoString:NULL] && [scanner scanString:@":" intoString:NULL]) {
[scanner scanCharactersFromSet:mimeTypeSet intoString:&mimeType];
}
GHAssertEqualStrings(@"application/xml", mimeType, @"Mime-type should be application/xml");
// Prepare to look for the charset attribute
NSString *charset = nil;
// Ignore quotes as well as whitespace
[scanner setCharactersToBeSkipped:[NSCharacterSet characterSetWithCharactersInString:@"\r\n\t \""]];
// Skip past the charset attribute declaration
if ([scanner scanUpToString:@"charset=" intoString:NULL]
&& [scanner scanString:@"charset=" intoString:NULL]) {
[scanner scanCharactersFromSet:charsetSet intoString:&charset];
}
GHAssertEqualStrings(@"utf-8", charset, @"Charset should be utf-8");
}
通过使用while循环读取“;然后检查它是否是我正在扫描的属性,可以使这变得更聪明。
我敢说它比使用regex更快地进行基准测试,而且我相当长的代码可以重构成更小的代码。