0

私は Cocoa プログラミングにまったく慣れていないので、ユーザーがテキスト フィールドにテキストを入力してからボタンを押すプログラムを作成するために最善を尽くしています。ボタンが押されると、テキストは特定の部分文字列を特定の文字に置き換えることになっています。一部の部分文字列は 1 文字の長さですが、2 文字を超える部分文字列はありません。置換が実行された後、新しく取得されたテキストは別のテキストフィールドに配置されます。

部分文字列置換の例としては、"n" を "5" に変更する、"nj" を "g" に変更する、"ng" を "s" に変更するなどがあります。だから、「注射器を今すぐ注入してください!」というテキスト。「Igect the syrise 5ow!」に変更されます。

シンプルでエレガントな方法でこれを達成するにはどうすればよいですか? 次のコードを試しましたが、うまくいかないようです。

- (IBAction)convert:(id)sender {
    NSMutableString *x;
    [x setString:[self.input stringValue]];
    NSMutableString *output1;
    [output1 setString:@""];
    NSMutableString *middle;
    middle = [[NSMutableString alloc] init];
    int s;
    unsigned long length = [x length];
    for (s = 0; s < length; s = s + 1) {
        if (s + 2 <= length) {            // if more than or equal to two characters left
            [middle setString:[x substringWithRange:NSMakeRange(s, 2)]];
            if ([middle isEqualToString:@"nj"]) {
                [output1 appendToString:@"g"];
                s = s+1;
            } else if ([middle isEqualToString:@"ng"]) {
                [output1 appendToString:@"s"];
                s = s+1;
            } else {                      // if no two-character sequence matched
                [middle setString:[x substringWithRange:NSMakeRange(s, 1)]];
                if ([middle isEqualToString:@"n"]) {
                    [output1 appendString:@"5"];
                }
            }
        } else {                          // if less than two characters left
            [middle setString:[x substringWithRange:NSMakeRange(s, 1)]];
            if ([middle isEqualToString:@"n"]) {
                [output1 appendString:@"5"];
            }
        }
    }
    [self.output setStringValue:output1];
}

ここで、*xはテキストのinput送信元で*output1あり、 は結果が格納される場所であり、*middleテスト対象のテキストで構成されinputoutputNSTextFieldです。

4

1 に答える 1

0

かなりの数の異なる方法で、あなたが望むものを達成できると思います。ここに簡単なものがあります:

  1. 値/置換のマップを定義する
  2. 長さ順に並べ替えます(長さが大きい順)
  3. 一致して置換

おそらくこのようなもの:

#import <Foundation/Foundation.h>

NSString * matchAndReplace(NSString *input, NSDictionary *map){

    NSMutableString *_input = [input mutableCopy];

    // Get all keys sorted by greatest length
    NSArray *keys = [map.allKeys sortedArrayUsingComparator: ^(NSString *key1, NSString *key2) {
        return [@(key2.length) compare:@(key1.length)];
    }];

    for (NSString *key in keys) {
        [_input replaceOccurrencesOfString:key
                                withString:map[key]
                                   options:NSLiteralSearch
                                     range:NSMakeRange(0,_input.length)];
    }
    return [_input copy];

};

int main(int argc, char *argv[]) {
    @autoreleasepool {
        NSDictionary *mapping = @{
            @"n": @"5",
            @"nj": @"g",
            @"ng": @"s"
        };

        NSString *input = @"Inject the syringe now!";

        NSLog(@"Output: %@", matchAndReplace(input, mapping));
    }
}

どちらが生成されますか:

出力: syrise 5ow を igect!

注: これは、(明らかに) 目的を達成するための過度に単純化された方法であり、すべてのエッジ ケースをカバーするためにいくつかの調整が必要になる場合がありますが、あなたのバージョンよりも単純であり、役立つことを願っています。

于 2014-05-24T20:31:43.690 に答える