Лучший способ разбить строку на токены, пропуская экранированные разделители? - PullRequest
1 голос
/ 13 февраля 2010

Я получаю NSString, который использует запятые в качестве разделителей и обратную косую черту в качестве escape-символа. Я пытался разбить строку, используя componentsSeparatedByString, но я не нашел способа указать escape-символ. Есть ли встроенный способ сделать это? NSScanner? CFStringTokenizer

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

Теперь, когда я думаю об этом, мне нужно проверить, чтобы количество escape-символов перед разделителем было четным, потому что только тогда сам разделитель не экранируется.

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

Ответы [ 3 ]

1 голос
/ 13 февраля 2010

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

  1. если вы обнаружите обратную косую черту, игнорируйте, но скопируйте следующий символ (если существует) безоговорочно
  2. если вы найдете запятую, конец этого раздела

Вы можете сделать это вручную или использовать некоторые функции NSScanner, чтобы помочь вам (scanUpToCharactersFromSet: intoString:)

0 голосов
/ 14 февраля 2010

Хорошо, (я надеюсь) это то, что предложил Виполяр. Это первая реализация, которая работает. Я только начал с языка, не собранного GC, поэтому, пожалуйста, оставьте комментарий, если считаете, что этот код можно улучшить, особенно в отделе управления памятью.

- (NSArray *) splitUnescapedCharsFrom: (NSString *) str atChar: (char) delim withEscape: (char) esc
{
    NSMutableArray * result = [[NSMutableArray alloc] init];
    NSMutableString * currWord = [[NSMutableString alloc] init];

    for (int i = 0; i < [str length]; i++)
    {
        if ([str characterAtIndex:i] == esc)
        {
            [currWord appendFormat:@"%c", [str characterAtIndex:++i]];
        }
        else if ([str characterAtIndex:i] == delim)
        {
            [result addObject:[NSString stringWithString:currWord]];
            [currWord release];
            currWord = [[NSMutableString alloc] init];
        }
        else
        {
            [currWord appendFormat:@"%c", [str characterAtIndex:i]];
        }
    }

    [result addObject:[NSString stringWithString:currWord]];
    [currWord release];

    return [NSArray arrayWithArray:result];
}
0 голосов
/ 13 февраля 2010

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

...