ios - 如何从索引到索引解析NSString?

标签 ios nsstring nsrange

我想解析这样的字符串:
NSString *str = @"firstcolumn second column text Third Column Text";

我有三栏文字,每一栏可以是带有空格的文字。
我知道列的宽度,col1 = 10个字符长,col2 = 20,col3 = 30
我知道我可以使用NSRange(0,len1),(10,len2),(20,len3)。

我遇到崩溃“超出范围”错误,因为长度变化,列文本的长度不必达到其最大限制。

任何想法如何做到这一点?

NSString *str = @"A000 B11 This is text description This column is a longer Text description"; 
//A000 column can be 10 chars long
//B11 can be 20 chars
//This is some text description can be 30 characters long
 NSString *code1 = [line substringWithRange:NSMakeRange(0,10)];
 NSString *code2 = [line substringWithRange:NSMakeRange(10,20)];
 NSString *shorttext = [line substringWithRange:NSMakeRange(20,20)];
 NSString *longtext = [line substringWithRange:NSMakeRange(30,30)];


我想在上面的示例中获得code1 = A000,它的长度可以是10个字符,但不必像您看到的那样。相同,其他两列分别是code2和text。
我怎样才能做到这一点?

最佳答案

如果我理解正确,则您有一个输入NSString str,它由三个串联的字符串组成:col1col2col3。此外,您知道有关该问题的以下约束


col1介于0到10个字符之间
col2介于0到20个字符之间
col3介于0到30个字符之间


并想从str恢复这些字符串。换句话说,您要唯一地确定col1col2col3,以使str等于

[NSString stringWithFormat:@"%@%@%@", col1, col2, col3];


不幸的是,正如其他人所评论的那样,如果不解决问题,这是不可能的。要了解为什么不考虑这种情况,

str = @"a";


在这种情况下,您知道组件字符串之一(col1col2col3)等于@"a",而其他两个字符串等于@""。但是,无法确定哪个。例如,如果col1 = @"a"以及col2col3都等于@"";然后

[NSString stringWithFormat:@"%@%@%@", col1, col2, col3]


评估为

@"a"


如预期的。但是,如果col1col2等于@""col3 = @"a",则也是如此,因为

[NSString stringWithFormat:@"%@%@%@", col1, col2, col3]


仍然评估为

@"a"


这里的问题不是组件字符串可以为空,而是它们可以在一定范围内变化。

如果我们限制问题以使长度正确


col1,长度为10个字符
col2,长度为20个字符
col3,长度为30个字符


然后可以使用以下功能恢复str

void GetColumnsFromString(NSString *str, NSString * __autoreleasing *col1, NSString * __autoreleasing *col2, NSString * __autoreleasing *col3)
{
    if (col1) {
        *col1 = [str substringWithRange:NSMakeRange(0, 10)];
    }
    if (col2) {
        *col2 = [str substringWithRange:NSMakeRange(10, 20)];
    }
    if (col3) {
        *col3 = [str substringWithRange:NSMakeRange(30, 30)];
    }
}


如注释中所述,另一个更好的解决方案是使用str中的“特殊”字符来划分组件字符串之间的边界。如果我们这样构造str

str = [NSString stringWithFormat:@"%@%@%@", col1, col2, col3];


并且我们限制col1col2col3不包含字符,那么我们可以按如下方式解析col1col2

NSArray *cols = [str componentsSeparatedByString:@""];
col1 = cols[0];
col2 = cols[1];
col3 = cols[2];


如果使用空格字符代替字符,情况也没有什么不同。

编辑:您添加了有关输入字符串和所需输出的更多信息:

而不是三个,有四个组件字符串:col1col2col3col4。我们有一些有关它们的信息:


col1的长度在0到10个字符之间
col1不包含空格字符
col2的长度在0到20个字符之间
col2不包含空格字符
col3的长度在0到30个字符之间
col3可能包含空格字符
col4的长度不受限制
col4可能包含空格字符


此外,四个字符串在它们的串联中由空格分隔。因此,您的目标是唯一确定col1col2col3col4,因此str等于

[NSString stringWithFormat:@"%@ %@ %@ %@", col1, col2, col3, col4];


在这种情况下,可以使用NSScanner提取col1col2

NSScanner *scanner = [NSScanner scannerWithString:str];
NSCharacterSet *spaceCharacterSet = [NSCharacterSet characterSetWithCharactersInString:@" "];
NSString *col1 = nil, *col2 = nil;
[scanner scanUpToCharactersFromSet:spaceCharacterSet intoString:&col1];
[scanner scanUpToCharactersFromSet:spaceCharacterSet intoString:&col2];


此时,可以提取字符串remainder,其中包含两个最终的字符串col3col4,中间用空格隔开:

NSCharacterSet *emptyCharacterSet = [NSCharacterSet characterSetWithCharactersInString:@""];
NSString *remainder = nil;
[scanner scanUpToCharactersFromSet:emptyCharacterSet intoString:&remainder];


至此,您又回到了我开头所描述的那种情况。您有一个字符串(remainder),该字符串由两个用空格分隔的组成部分字符串(col3col4)组成。检测这两个字符串之间的边界的唯一方法是该空格。

但是,col3可能包含空格。如果不能,那么您可以简单地扫描直到到达下一个空格,然后将开始和该空格之间的内容提取到col3并将其余内容提取到col4

另外,col4也可以包含空格。如果不能,则可以从remainder的末尾开始扫描,直到到达末尾的第一个空格,然后将该范围提取到col4,将其余范围提取到col3

关于ios - 如何从索引到索引解析NSString?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13261337/

相关文章:

ios - popViewController 而 pushViewController 正在动画导致导航栏损坏

ios - UiTextView 使用表情符号移动到下一个字符错误

iphone - 如何突出显示字符串的NSRange

ios - 如何在 Objective-c 中获取数组类型 [1,2] 而不是 (1, 2)?

iphone - 如何在 HTML 文档中找到数字然后用作 NSString?

ios - 我如何使用带整数的 NSRange 来简化我的代码?

iphone - 为 UITableViewCells 使用背景图像(分组样式)- 角不圆

ios - stringFromDate 和 dateFromString 有时会返回 null

ios - 是否可以在 iOS 5.1.1 iPad 设备中运行使用 5.0 SDK 部署的 iPhone 应用程序

iphone - 发行时NSString崩溃