I have a NSString that looks something like this "ALAssetsGroup - Name:Hej - ProgCam, Type:Album, Assets count:0" I want to "extract" the name "Hej". I tried to do it like this:

NSString *sStr = [NSString stringWithFormat:@"%@", assetGroups[indexPath.row]];
NSRange range1 = [sStr rangeOfString:@"Name: "];
NSRange range2 = [sStr rangeOfString:@" - ProgCam"];
NSRange rRange = {range1.location + range1.length, range2.location};
NSString *rStr = [sStr substringWithRange:rRange];
cell.cellLabel.text = [NSString stringWithFormat:@"%@", rStr];

But i get this error:

*** Terminating app due to uncaught exception 'NSRangeException', reason: 
'-[__NSCFString substringWithRange:]: Range or index out of bounds'

What am I doing wrong here?

有帮助吗?

解决方案 3

Below should work. I had to use similar to parse HTML for screen scrapes. Looking for text in NSString based on search characters should be satisfied below. Put the beginning string first, then componentsSeparatedByString at index 0 as the terminating.

*Note - This returns the first instance. If there are other instances, they'll be ignored in the NSString

 NSString *sStr = [NSString stringWithFormat:@"%@", assetGroups[indexPath.row]];
 NSString *name= [[[[sStr componentsSeparatedByString:@"Name:"] objectAtIndex:1] componentsSeparatedByString:@" - ProgCam"] objectAtIndex:0]; 
 cell.cellLabel.text = [NSString stringWithFormat:@"%@", name];

其他提示

You have to subtract the range1.location + range1.length from range2.location:

NSInteger start = range1.location + range1.length;
NSRange rRange = {start, range2.location - start};

Just an alternative based on a regular expression (aka regex) to get the range directly without having to calculate it yourself:

// A regex pattern to match everything between "Name:" and " - ProgCam"
NSString *pattern = @"(?<=Name:).*?(?= - ProgCam)";

NSRange rRange = [sStr rangeOfString: pattern options: NSRegularExpressionSearch];

To dissect the regex:

(?<=XXX)

Begin with XXX (in your case this is the "Name:" part). This is a positive lookbehind that matches XXX. It means that XXX must be there, but it will not be considered a part of the matched string.

.*?

... followed directly by anything (represented by the dot) zero or more times (the asterisk). The question mark means that it should make the match as small as possible. In this case if there are two YYY (in the example below) in the string, it will pick the first. Since you don't have that problem in your string, you don't really need it, but it makes the pattern more robust in case things change in the future.

(?=YYY)

... up to YYY (in your case this is the " - ProgCam" part). This is a positive lookahead that matches YYY. It means that YYY must be there, but it will not be considered a part of the matched string.

There's no specific need to keep the pattern in its own variable, that's just for readability. If you prefer oneliners, you can stick it all on a single line.

There are many tutorials on the net, for instance this one.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top