2012-11-07 20 views
0

我想解析字符串是這樣的:
NSString *str = @"firstcolumn second column text Third Column Text";如何解析NSString從索引到索引?

我有文字的三列,每列可以是文本與空間。我知道我可以使用NSRange(0,len1),(10,len2),(20,len3)。我知道我有多寬的列,col1 = 10字符長,col2 = 20,col3 = 30

我得到崩潰「超出範圍」錯誤,因爲長度變化,列文本的長度沒有達到它的最大限制。

任何想法如何做到這一點?

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個字符,但不一定像你所看到的一樣,同樣的,其他2列,code2和text 。 我該怎麼辦?

+0

如果你正在崩潰,你能分享代碼,以便有人可以幫助你嗎? – bryanmac

+0

那麼每一列的長度都不一樣?你在列文本中有空格嗎?你沒有任何分隔符? – calimarkus

+0

你所說的只有在最後一列可變長時纔有效。如果前2列可以是可變長度,那麼每列之間必須有一些分隔符。 – rmaddy

回答

1

如果我理解正確,你具有輸入NSStringstr,其由三個級聯字符串組成:col1col2col3。此外,您瞭解這個問題,

  • col1是介於0和10個字符
  • col2爲0至20個字符
  • col3是以下約束

    和介於0和30個字符

想要從 str恢復這些字符串。換句話說,你要 唯一確定 col1col2col3使 str等於

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

不幸的是,正如其他人評論說,這是不可能的,而無需修改問題。要知道爲什麼不考慮的情況下

str = @"a"; 

在這種情況下,你就知道該組件串(col1col2,或col3)的一個等於@"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]; 

的情況如果不使用字符,則使用空格字符。

編輯:你增加了有關輸入字符串和期望輸出的更多信息:

,而不是三個,有組件串:col1col2col3,和col4。我們有一些關於他們的信息:

  • col1
  • col1不包含空格字符
  • col2是介於0和10個字符之間0和20長
  • col2不包含字符空格字符
  • col3長度在0到30個字符之間
  • col3MAY包含空格字符
  • col4未在長度約束
  • col4MAY包含空格字符

此外,四個字符串由空格在他們的級聯分離。所以,你的目標是唯一確定col1col2col3,並col4所以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

+0

感謝您的詳細解答。我無法在字符串之間插入分隔符。該文檔由一些第三方機構生成,但我相信它們可能具有XML版本的文件,這對我來說可能是另一種選擇,我相信這裏有一些XML解析器。 – SMA2012

+0

@Nate你說過*如果不是使用空格字符的字符,情況就不同了。*。這是不正確的。如果你調用'[str componentsSeparatedByString:@「」];'那麼第三列被分割成一堆,因爲它的值可以包含空格。其他答案很好,否則。 – rmaddy

+0

@maddy我明白你的觀點,但這不是我想表達的意思。我的意思是,這種情況並沒有什麼不同,如果不是制約'col1'和'col2'和'col3'不包含字符'',我們限制他們不包含空格字符。在這種情況下,我們將能夠執行'[str componentsSeparatedByString:@「」]'並根據需要獲取不同的組件字符串。 –