Tokenize NSString дважды в Objective-C - PullRequest
1 голос
/ 27 июня 2011

У меня нет большого опыта в объективе-c, извините, если это действительно очевидно.

Мне нужно разделить строку NSString на токены.Жетоны разделены пробелами или другим знаком (не буквой).Подвох в том, что я хочу сохранить разделители за исключением случаев, когда они являются пробелами.

Пример фразы: "abc, d's, e f."из этого я хотел бы получить:

"a"
"b"
"c"
","
"d"
"'"
"s"
","
"e"
"f"
"."

С этим кодом:

NSMutableCharacterSet *separators = [NSMutableCharacterSet punctuationCharacterSet];
[separators formUnionWithCharacterSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

NSArray *parse_array = [intext componentsSeparatedByCharactersInSet:separators];

Я получаю только буквы.Если я просто фильтрую пробелы и NL, я получаю знаки вместе с буквами.Мне нужно выполнить два последовательных разбора (сначала пробелы и Nl, а затем пунктуацию), но я действительно не знаю, как это сделать в target-c.Кто-нибудь может дать мне подсказку?

Спасибо!

Ответы [ 3 ]

5 голосов
/ 13 октября 2011

Ознакомьтесь с моим открытым исходным кодом набора инструментов для анализа / разбора строки какао: ParseKit:

http://parsekit.com

ParseKit содержит чрезвычайно мощный / гибкий класс токенизатора: PKTokenizer.По умолчанию PKTokenizer будет молча потреблять маркеры пробелов, не сообщая о них.(В этом случае это то, что вы хотите, но это поведение можно настроить, если вы этого не сделаете.)

Вот как вы можете использовать PKTokenizer для этой конкретной задачи:

// create the tokenizer with your string
NSString *inStr = @"a b c,d's, e f.";
PKTokenizer *t = [PKTokenizer tokenizerWithString:inStr];

// configure the tokenizer to not allow apostrophes inside words (that's the default)
[t.wordState setWordChars:NO from:'\'' to:'\''];

// loop thru the input and concat the non-whitespace chars
PKToken *eof = [PKToken EOFToken];
PKToken *tok = nil;

NSMutableArray *outStrs = [NSMutableArray array];
while ((tok = [t nextToken]) != eof) {
    [outStrs addObject:tok.stringValue];
}

outStrs содержит:

"a" "b" "c" "," "d" "'" s "", "" e "" f "". "

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

3 голосов
/ 27 июня 2011

Ну, вы можете сделать что-то вроде этого, чтобы удалить все пробелы из строки:

NSArray * t = [string componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
string = [t componentsJoinedByString:@""];

Тогда вы можете просто перебрать символы и превратить их в NSStrings:

NSMutableArray *tokens = [NSMutableArray array];
for (NSUInteger i = 0; i < [string length]; ++i) {
  unichar character = [string characterAtIndex:i];
  NSString *token = [NSString stringWithFormat:@"%C", character];
  [tokens addObject:token];
}
NSLog(@"%@", tokens);

Или, если вы раньше не хотели удалять пробелы, вы можете сделать это в цикле:

NSMutableArray *tokens = [NSMutableArray array];
for (NSUInteger i = 0; i < [string length]; ++i) {
  unichar character = [string characterAtIndex:i];
  if ([[NSCharacterSet whitespaceCharacterSet] characterIsMember:character]) {
    continue;
  }
  NSString *token = [NSString stringWithFormat:@"%C", character];
  [tokens addObject:token];
}
NSLog(@"%@", tokens);
0 голосов
/ 28 июня 2011

Я получил его для работы с этим кодом.Это работает для букв или слов:

//parse the phrase into tokens. Punctuation will be tokenized too.
NSMutableArray *tokens = [NSMutableArray array];
NSInteger last_word_start = -1;
//
for (NSUInteger i = 0; i < [myPhrase length]; ++i) 
{
    unichar character = [myPhrase characterAtIndex:i];
    if ([[NSCharacterSet whitespaceCharacterSet] characterIsMember:character]) 
    {
        if (last_word_start >= 0) 
            [tokens addObject:[myPhrase substringWithRange:NSMakeRange(last_word_start, i-last_word_start)]];
        last_word_start = -1;
    }
    else
    {
        if ([[NSCharacterSet punctuationCharacterSet] characterIsMember:character])
        {
            if (last_word_start >= 0) 
                [tokens addObject:[myPhrase substringWithRange:NSMakeRange(last_word_start, i-last_word_start)]];
            [tokens addObject:[NSString stringWithFormat:@"%C", character]];
            last_word_start = -1;
        }
        else
        {
            if (last_word_start == -1)
                last_word_start = i;
        }
    }
}
//save pending letters
if (last_word_start >= 0) 
    [tokens addObject:[myPhrase substringWithRange:NSMakeRange(last_word_start, [myPhrase length]-last_word_start)]];
NSLog(@"Tokens for phrase '%@':",myPhrase);
NSLog(@"%@", tokens);

Спасибо!

...