Я ищу простой, эффективный способ преобразовать строки в CamelCase для подчеркивания нотации (т.е. MyClassName-> my_class_name) и назад снова в Objective C.
Мое текущее решение включает много из rangeOfString
, characterAtIndex
, и replaceCharactersInRange
операции на NSMutableStrings, и просто ужасны как ад:) Кажется, что должно быть лучшее решение, но я не уверен, каково это.
Я не импортировал бы regex библиотеку только для этого варианта использования, хотя это - опция, если все остальное перестало работать.
Предложение Криса о RegexKitLite - хорошее. Это отличный инструментарий, но это можно легко сделать с помощью NSScanner . Используйте -scanCharactersFromSet: intoString:
, чередуя + uppercaseLetterCharacterSet
и + lowercaseLetterCharacterSet
. Чтобы вернуться назад, вы должны использовать -scanUpToCharactersFromSet:
вместо этого, используя набор символов, содержащий только подчеркивание.
Если вас беспокоит только видимость вашего кода, вы можете создать категорию для NSString
с использованием уже разработанных вами методов. Таким образом, вы увидите ужасный беспорядок только один раз. ;)
Например:
@interface NSString(Conversions) {
- (NSString *)asCamelCase;
- (NSString *)asUnderscored;
}
@implementation NSString(Conversions) {
- (NSString *)asCamelCase {
// whatever you came up with
}
- (NSString *)asUnderscored {
// whatever you came up with
}
}
РЕДАКТИРОВАТЬ : После быстрого поиска в Google я не смог найти никакого способа сделать это, даже на простом языке C. Однако я нашел фреймворк, который может быть полезен. Он называется RegexKitLite . Он использует встроенную библиотеку ICU, поэтому он добавляет только около 20 КБ к окончательному двоичному файлу.
Как насчет этого:
NSString *MyCamelCaseToUnderscores(NSString *input) {
NSMutableString *output = [NSMutableString string];
NSCharacterSet *uppercase = [NSCharacterSet uppercaseLetterCharacterSet];
for (NSInteger idx = 0; idx < [input length]; idx += 1) {
unichar c = [input characterAtIndex:idx];
if ([uppercase characterIsMember:c]) {
[output appendFormat:@"_%@", [[NSString stringWithCharacters:&c length:1] lowercaseString]];
} else {
[output appendFormat:@"%C", c];
}
}
return output;
}
NSString *MyUnderscoresToCamelCase(NSString *underscores) {
NSMutableString *output = [NSMutableString string];
BOOL makeNextCharacterUpperCase = NO;
for (NSInteger idx = 0; idx < [underscores length]; idx += 1) {
unichar c = [underscores characterAtIndex:idx];
if (c == '_') {
makeNextCharacterUpperCase = YES;
} else if (makeNextCharacterUpperCase) {
[output appendString:[[NSString stringWithCharacters:&c length:1] uppercaseString]];
makeNextCharacterUpperCase = NO;
} else {
[output appendFormat:@"%C", c];
}
}
return output;
}
Некоторые недостатки заключаются в том, что они действительно используют временные строки для преобразования между верхним и нижним регистром, и у них нет никакой логики для акронимов, поэтому myURL приведет к my_u_r_l.