Лучший способ избежать символов, таких как символ новой строки и двойные кавычки в NSString - PullRequest
10 голосов
/ 24 февраля 2009

Скажем, у меня есть NSString (или NSMutableString), содержащая:

I said "Hello, world!".
He said "My name's not World."

Какой лучший способ превратить это в:

I said \"Hello, world!\".\nHe said \"My name\'s not World.\"

Нужно ли вручную использовать -replaceOccurrencesOfString:withString: снова и снова, чтобы экранировать символы, или есть более простой способ? Эти строки могут содержать символы из других алфавитов / языков.

Как это делается на других языках с другими строковыми классами?

Ответы [ 7 ]

5 голосов
/ 22 апреля 2010

stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding

4 голосов
/ 18 марта 2010

Это позволит избежать двойных кавычек в строке NSString:

NSString *escaped = [originalString stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""];

Так что вам нужно быть осторожным и избегать побега персонажа ...

4 голосов
/ 24 февраля 2009

Я не думаю, что есть какой-либо встроенный метод для "экранирования" определенного набора символов.

Если символы, которые вы хотите экранировать, четко определены, я бы, вероятно, придерживался предложенного вами простого решения, грубо заменяя экземпляры символов.

Имейте в виду, что если в исходной строке уже есть экранированные символы, вам, вероятно, следует избегать их двойного экранирования. Одним из способов достижения этой цели было бы пройти через «unescape» любые экранированные строки символов в строке, а затем снова экранировать их все.

Если вам нужно поддерживать набор переменных экранированных символов, взгляните на методы NSScanner "scanUpToCharactersFromSet: intoString:" и "scanCharactersFromSet: intoString:". Вы можете использовать эти методы в NSScanner, чтобы перемещаться по строке, копировать части из раздела «scanUpTo» в изменяемую строку без изменений и копировать части из определенного набора символов только после их экранирования.

3 голосов
/ 04 ноября 2010

Я думаю, что в подобных случаях полезно работать с символом одновременно, в байтах UniChars или UTF8. Если вы используете UTF-8, то vis(3) сделает большую часть работы за вас (см. Ниже). Могу ли я спросить, почему вы хотите экранировать одинарные кавычки в строке с двойными кавычками? Как вы планируете обрабатывать многобайтовые символы? В приведенном ниже примере я использую UTF-8, кодируя 8-битные символы, используя восьмеричные символы в стиле C Это также может быть отменено unvis(3).

#import <Foundation/Foundation.h>
#import <vis.h>

@interface NSString (Escaping)

- (NSString *)stringByEscapingMetacharacters;

@end

@implementation NSString (Escaping)

- (NSString *)stringByEscapingMetacharacters
{
    const char *UTF8Input = [self UTF8String];
    char *UTF8Output = [[NSMutableData dataWithLength:strlen(UTF8Input) * 4 + 1 /* Worst case */] mutableBytes];
    char ch, *och = UTF8Output;

    while ((ch = *UTF8Input++))
        if (ch == '\'' || ch == '\'' || ch == '\\' || ch == '"')
        {
            *och++ = '\\';
            *och++ = ch;
        }
        else if (isascii(ch))
            och = vis(och, ch, VIS_NL | VIS_TAB | VIS_CSTYLE, *UTF8Input);
        else
            och+= sprintf(och, "\\%03hho", ch);

    return [NSString stringWithUTF8String:UTF8Output];
}

@end

int
main(int argc, const char *argv[])
{
    NSAutoreleasePool *pool = [NSAutoreleasePool new];

    NSLog(@"%@", [@"I said \"Hello, world!\".\nHe said \"My name's not World.\"" stringByEscapingMetacharacters]);

    [pool drain];
    return 0;
}
2 голосов
/ 18 мая 2012

Это фрагмент, который я использовал в прошлом, который работает довольно хорошо:

- (NSString *)escapeString:(NSString *)aString
{
    NSMutableString *returnString = [[NSMutableString alloc] init];

    for(int i = 0; i < [aString length]; i++) {

        unichar c = [aString characterAtIndex:i];

        // if char needs to be escaped
        if((('\\' == c) || ('\'' == c)) || ('"' == c)) {
            [returnString appendFormat:@"\\%c", c];            
        } else {
            [returnString appendFormat:@"%c", c];
        }
    }

    return [returnString autorelease];   
}
1 голос
/ 06 июля 2010

Сделайте это:

NSString * encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(
    NULL,
    (CFStringRef)unencodedString,
    NULL,
    (CFStringRef)@"!*'();:@&=+$,/?%#[]",
    kCFStringEncodingUTF8 );

Ссылка: http://simonwoodside.com/weblog/2009/4/22/how_to_really_url_encode/

0 голосов
/ 24 февраля 2009

Возможно, вы даже захотите изучить использование библиотеки регулярных выражений (доступно множество опций, популярный выбор - RegexKit). Не должно быть слишком сложно найти заранее написанное регулярное выражение для экранирования строк, обрабатывающих особые случаи, такие как существующие экранированные символы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...