【问题标题】:NSString: remove leading 0s so '00001234' becomes '1234'? [duplicate]NSString:删除前导 0 使“00001234”变为“1234”? [复制]
【发布时间】:2012-11-01 12:56:06
【问题描述】:

可能重复:
Removing leading zeroes from a string

我需要删除NSString 中的前导0,我能想到的一种快速方法是将字符串转换为NSNumber,然后转换回NSString,这将为我提供干净的字符串,尽管我'我不确定它是否有效。有没有其他方法可以做到这一点?

谢谢

【问题讨论】:

标签: objective-c ios nsstring


【解决方案1】:

所以只是为了好玩,我决定用各种方法来计时。这绝不是一项科学测试,主要是为了娱乐,但你们中的一些人可能还是想看看。

我创建了一个方法并替换了各种例程来处理表示数字 0 到 100,000 的字符串,所有这些字符串都带有三个前导 0。

但请记住,如果您只有一个(甚至一百个)这些字符串要修剪,那么即使是最慢的方法也完全可以接受。 (使用数字格式化程序大约需要 0.000012039905 秒,或大约 1/100 毫秒。)除非您确实需要处理一个充满像这样的字符串。我个人最喜欢的仍然是正则表达式,因为它相对较快,并且即使没有文档,您想要完成的what 也很明显。

以下是结果(从最快到最慢):

遍历字符串

// I tried this by looping through the utf8String and got the same times
// (actually, ever so slightly longer, probably since it had to create the c string)
//
// I did find that using `[string getCharacters:buffer range:range]` and
// iterating over the character buffer that it took another 0.01 seconds
// off the time.  Hardly worth it though.  :)
NSUInteger length = [string length];
for (NSUInteger i = 0; i < length; i++)
{
    if ([string characterAtIndex:i] != '0')
    {
        return [string substringFromIndex:i];
    }
}
return @"0";

// Time 1: 0.210126
// Time 2: 0.219159
// Time 3: 0.201496

转换为 int 再转换回 NSString

int num = [string intValue];
return [NSString stringWithFormat:@"%d", num];

// Time 1: 0.322206
// Time 2: 0.345259
// Time 3: 0.324954

long long num = [string longLongValue];
return [NSString stringWithFormat:@"%lld", num];

// Time 1: 0.364318
// Time 2: 0.344946
// Time 3: 0.364761
// These are only slightly slower, but you can do bigger numbers using long long

使用 NSScanner

NSScanner *scanner    = [NSScanner scannerWithString:string];
NSCharacterSet *zeros = [NSCharacterSet
                         characterSetWithCharactersInString:@"0"];
[scanner scanCharactersFromSet:zeros intoString:NULL];

return [string substringFromIndex:[scanner scanLocation]];

// Time 1: 0.505277
// Time 2: 0.481884
// Time 3: 0.487209

使用正则表达式

NSRange range = [string rangeOfString:@"^0*" options:NSRegularExpressionSearch];
return [string stringByReplacingCharactersInRange:range withString:@""];

// Time 1: 0.610879
// Time 2: 0.645335
// Time 3: 0.637690

使用静态数字格式化程序

static NSNumberFormatter *formatter = nil;
if (formatter == nil)
{
    formatter             = [NSNumberFormatter new];
    formatter.numberStyle = NSNumberFormatterDecimalStyle;
}

NSNumber *number = [formatter numberFromString:string];
return [formatter stringFromNumber:number];

// Time 1: 1.774198
// Time 2: 1.753013
// Time 3: 1.753893

使用数字格式化程序

NSNumberFormatter *formatter = [NSNumberFormatter new];
formatter.numberStyle        = NSNumberFormatterDecimalStyle;

NSNumber *number             = [formatter numberFromString:string];
return [formatter stringFromNumber:number];

// Time 1: 11.978336
// Time 2: 12.039905
// Time 3: 11.904984
// No wonder Apple recommends reusing number formatters!

【讨论】:

  • 出色的工作!如果您使用已编译的NSRegularExpression 而不是rangeOfString:options: 和NSRegularExpressionSearch,怎么样?我想每次使用相同的编译正则表达式会明显更快。
  • @dreamlax:我开始做那个,但不太了解正则表达式例程,无法快速将其组合在一起。如果你更了解它并能给我一个例子,我可以很容易地得到它的时间。
  • 没关系,我自己试了一下,在我的情况下它只快了 10% 左右。我认为它会比这更充实一些。尽管如此,这是一项改进,但除非您进行数百万次这样的替换,否则不值得担心:)
  • 酷,如果你想将这项技术分享给任何可能需要它的人,我可以将它添加到列表中。
【解决方案2】:

你可以使用正则表达式。

NSString *numStr = @"0001234";
NSRange range = [numStr rangeOfString:@"^0*" options:NSRegularExpressionSearch];
NSString *result = [numStr stringByReplacingCharactersInRange:range withString:@""];

如果您经常这样做(如数千次),您可能会受益于使用已编译的NSRegularExpression。

【讨论】:

  • +1,我更喜欢这种方法,而不是重复问题所采用的方法。 (也去添加它,大声笑。)
  • 我尝试搜索一些 NSString 的方法,例如 findFirstNotOf,但没有成功。你的回答比我的更有用。我会投票给你。
【解决方案3】:

这行得通,我已经测试过了。而且我认为这是一个非常好的方法。更少的代码更少的错误。 KISS.

NSString *numStr = @"000123";
int num = numStr.intValue;
numStr = [NSString stringWithFormat:@"%d", num];

【讨论】:

  • 这仅限于int 的范围,但对于大多数用途来说应该足够了。
  • 是的,这是直截了当的,并不是非常低效。可能在 characterAtIndex 上的简单循环后跟子字符串操作会更快,但更复杂且容易出错。
  • @HotLicks:实际上,这仅比您建议的方法效率低,并且大约是正则表达式方法的两倍。我会尽快发布我的时间。
  • @lnafziger -- 是的,无论使用哪种方案,新字符串的创建都将成为工作的最大份额,淹没字符计数或数字格式。最快的方法是将字符串的偏移量传递给下一阶段,该阶段将以某种方式执行子字符串或其他任何事情,但这种情况不太可能发生。
  • 顺便说一下,对于想要使用这种技术的人:使用 long long 而不是 int 几乎没有性能损失,并且可以处理更大的数字。
猜你喜欢
  • 2011-11-28
  • 1970-01-01
  • 2012-08-22
  • 1970-01-01
  • 2013-03-25
  • 1970-01-01
  • 1970-01-01
  • 2012-12-09
  • 2012-05-03
相关资源
最近更新 更多