I would like to parse a string like this:
NSString *str = @"firstcolumn second column text Third Column Text";
I have three columns of text, each column could be text with spaces.
I know how wide the columns, col1 = 10 chars long, col2 = 20, col3 = 30
I know I could use NSRange(0,len1),(10,len2),(20,len3).
I get crashes ‘Out of range” errors because the length varies, the length of the column text doesn’t have to reach its max limit.
Any ideas how to do this?
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)];
I would like to get code1 = A000 in the above example, this can be of length 10 chars long, but don’t have to be as you can see. Same, thing goes for the other 2 columns, code2, and text.
How can I do this?
If I understand correctly, you have an input
NSStringstrwhich consists of three concatenated strings:col1,col2, andcol3. Additionally, you know the following constraints about the problemcol1is between 0 and 10 characterscol2is between 0 and 20 characterscol3is between 0 and 30 charactersand want to recover these strings from
str. Put differently, you want to uniquely determinecol1,col2, andcol3so thatstris equal toUnfortunately, as others have commented, this is not possible without modifying the problem. To see why not, consider the case where
In this case, you know that one of the component strings (
col1,col2, orcol3) is equal to@"a"and the other two are equal to@"". However, it’s not possible to determine which. If, for examplecol1 = @"a"andcol2andcol3are both equal to@""; thenevaluates to
as desired. However this is also true if
col1andcol2are equal to@""andcol3 = @"a"sincestill evaluates to
The problem here is not that the component strings are able to be empty but rather that they’re able to vary over a range.
If we constrained the problem so that the lengths were exact
col1, which is 10 characters longcol2, which is 20 characters longcol3, which is 30 characters longit would then be possible to recover
strwith the following function:Another, better, solution, as has been mentioned in the comments, is to use “special” characters in
strto demarcate the boundary between the component strings. If we constructedstrlike thisand we constrained
col1andcol2andcol3not to contain the character, then we could parsecol1andcol2as follows:The situation is no different if instead of the
character you use the space character.Edit: You added more information about the input string and the desired output:
Rather than three, there are four component strings:
col1,col2,col3, andcol4. We have some information about them:col1is between 0 and 10 characters longcol1does not contain the space charactercol2is between 0 and 20 characters longcol2does not contain the space charactercol3is between 0 and 30 characters longcol3MAY contain the space charactercol4isn’t constrained in lengthcol4MAY contain the space characterAdditionally, the four strings are separated by spaces in their concatenation. So your goal is to uniquely determine
col1,col2,col3, andcol4sostris equal toYou can use an
NSScannerto extractcol1andcol2in this case:At this point, it’s possible to extract the string
remainderwhich contains the two final stringscol3andcol4separated by a space:At this point, you are back in the same sort of situation I described at the beginning. You have a string (
remainder) which consists of two component strings (col3andcol4) which are separated by a space. The only way to detect the border between these two strings is that space.However,
col3may contain spaces. If it could not, then you could simply scan along until the next space was reached and extract the contents between the beginning and that space intocol3and the rest intocol4.In addition,
col4may also contain spaces. If it could not, then you could scan from the end ofremainderuntil the first space from the end was reached, extract that range intocol4and the rest intocol3.