簡體   English   中英

如何創建格式化的本地化字符串?

[英]How to create a formatted localized string?

我有一個本地化的字符串,需要采取一些變量。 但是,在本地化中,變量的順序可能會因語言而異。

所以這不是一個好主意:

NSString *text = NSLocalizedString(@"My birthday is at %@ %@ in %@", nil);

在某些語言中,某些詞語出現在其他語言之前,而在其他語言中則是相反的。 我目前缺乏一個很好的例子。

如何在格式化字符串中提供NAMED變量? 沒有一些沉重的自制字符串替換,有沒有辦法做到這一點? 即使是一些編號變量,如{%@ 1},{%@ 2}等也足夠......是否有解決方案?

這就是NSLocalizedString采用兩個參數的原因。 使用第二個參數包含描述變量的本機語言含義的注釋。 然后,翻譯人員可以使用$ +數字結構重新排序它們。 請參閱Apple的Localizing Notes

但是,您不能跳過一種語言的參數。 例如,如果您有3個英語參數和4個法語參數,並且您不需要英語中的第三個參數,則不能格式化為%1$@ %2$@ and %4$@ 你只能跳過最后一個。

格式化本地化字符串示例:

NSString *today = [MyHandWatch today];
NSString *msg = [NSString stringWithFormat:NSLocalizedString(@"Today is %@", @""), today];

genstrings將在Localizable.strings文件中生成此行:

"Today is %@" = "Today is %@";

幾個星期前,我通過使用NSScanner構建自己的簡單模板系統解決了這個問題。 該方法使用模板系統查找具有語法${name}變量。 變量通過NSDictionary提供給方法。

- (NSString *)localizedStringFromTemplateString:(NSString *)string variables:(NSDictionary *)variables {
    NSMutableString *result = [NSMutableString string];
    // Create scanner with the localized string
    NSScanner *scanner = [[NSScanner alloc] initWithString:NSLocalizedString(string, nil)];
    [scanner setCharactersToBeSkipped:nil];

    NSString *output;

    while (![scanner isAtEnd]) {
        output = NULL;
        // Find ${variable} templates
        if ([scanner scanUpToString:@"${" intoString:&output]) {
            [result appendString:output];

            // Skip syntax
            [scanner scanString:@"${" intoString:NULL];

            output = NULL;

            if ([scanner scanUpToString:@"}" intoString:&output]) {
                id variable = nil;
                // Check for the variable
                if ((variable = [variables objectForKey:output])) {
                    if ([variable isKindOfClass:[NSString class]]) {
                        // NSString, append
                        [result appendString:variable];
                    } else if ([variable respondsToSelector:@selector(description)]) {
                        // Not a NSString, but can handle description, append
                        [result appendString:[variable description]];
                    }
                } else {
                    // Not found, localize the template key and append
                    [result appendString:NSLocalizedString(output, nil)];
                }
                // Skip syntax
                [scanner scanString:@"}" intoString:NULL];
            }
        }
    }

    [scanner release];

    return result;
}

使用如下所示的localize文件:

"born message"  = "I was born in ${birthYear} on a ${birthWeekDay}. ${byebye}";
"byebye"        = "Cheers!";

我們可以完成以下結果......

NSDictionary *variables = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:1986], @"birthYear", @"monday", @"birthWeekDay", nil];
NSString *finalString [self localizedStringFromTemplateString:@"born message" variables:variables];
NSLog(@"%@", finalString); // "I was born in 1986 on a monday. Cheers!"

如您所見,我還添加了一些額外的功能。 首先,任何未找到的變量(在我的示例中${byebye} )都將被本地化並附加到結果中。 我這樣做是因為我從我的應用程序包中加載了HTML文件並通過localize方法運行它們(當這樣做時,我不會在創建掃描程序時本地化輸入字符串)。 此外,我添加了除了NSString對象之外的其他功能,以獲得一些額外的靈活性。

這段代碼可能不是性能最好或最漂亮的代碼,但它可以在沒有任何明顯性能影響的情況下完成工作:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM