如何在一个字符串中寻找到你想要的字符串(目标字符串)的所有位置?
例如: 在下面字符串中找到所有"我是"的 range
string = "...我是....是,,,,,...我是,,.是,,..我是...不...是,,,,.我...,,我是.."
swift4.2
func findAimstrAllRange(baseStr : NSString, aimStr: String, baseRange : NSRange, result : inout Array<NSRange>) -> Array<NSRange> {
let range = baseStr.range(of: aimStr, options: NSString.CompareOptions.literal, range: baseRange)
//找到
if range.length > 0{
result.append(range)
let detectLength = range.location + range.length
let rangeNew = NSRange(location: detectLength, length: baseStr.length - detectLength)
_ = findAimstrAllRange(baseStr: baseStr, aimStr: aimStr, baseRange: rangeNew, result: &result)
}
return result
}
//使用
let baseStr = "...我是....是,,,,,...我是,,.是,,..我是...不...是,,,,.我...,,我是.." as NSString
let aimStr = "我是"
var rangeArr = Array<NSRange>()
let result = findAimstrAllRange(baseStr: baseStr, aimStr: aimStr, baseRange: NSRange(location:0, length: baseStr.length), result: &rangeArr)
print(result)
Objective-C
- (void)viewDidLoad {
[super viewDidLoad];
NSString *baseStr = @"...我是....是,,,,,...我是,,.是,,..我是...不...是,,,,.我...,,我是..";
NSString *aimStr = @"我是";
NSMutableArray *result = [NSMutableArray array];
result = [self findAimstrAllRangeWithBaseStr:baseStr andAimStr:aimStr andBaseRange:NSMakeRange(0, baseStr.length) resultArr:result];
NSLog(@"%@",result);
}
-(NSMutableArray *)findAimstrAllRangeWithBaseStr:(NSString *)baseStr andAimStr:(NSString*)aimStr andBaseRange:(NSRange)baseRange resultArr:(NSMutableArray *)resultArr
{
NSRange range = [baseStr rangeOfString:aimStr options:NSLiteralSearch range:baseRange];
if (range.length > 0) {
[resultArr addObject:NSStringFromRange(range)];
NSUInteger nextLocation = range.location + range.length;
NSRange rangeNew = NSMakeRange(nextLocation, baseStr.length - nextLocation);
[self findAimstrAllRangeWithBaseStr:baseStr andAimStr:aimStr andBaseRange:rangeNew resultArr:resultArr];
}
return resultArr;
}
应用案例
实现微信点赞列表, 点击人名对应跳转相应的个人界面
方式一: label 中实现点击文字: 使用 YYLabel(需要传递 range 参数)
方式二: UITextView 实现点击文字,原生方法(同样需要 range 参数)
//稍微对上述方法进行修改
func findAimstrAllRange(baseStr : NSString, aimStr: String, baseRange : NSRange, result : inout Array<NSRange>) -> Array<NSRange> {
let range = baseStr.range(of: aimStr, options: NSString.CompareOptions.literal, range: baseRange)
if result.contains(range) == false {
result.append(range)
return result
}else{
//找到
if range.length > 0{
let detectLength = range.location + range.length
let rangeNew = NSRange(location: detectLength, length: baseStr.length - detectLength)
_ = findAimstrAllRange(baseStr: baseStr, aimStr: aimStr, baseRange: rangeNew, result: &result)
}
}
return result
}
let testArr = ["小明","小红","小绿","小红","小花","小明"]
//把人名数组通过 split 变成 baseStr
let baseStr = "小明,小红,小绿,小红,小花,小明" as NSString
var rangeArr = Array<NSRange>()
for str in testArr{
let arr = findAimstrAllRange(baseStr: baseStr, aimStr: str, baseRange: NSRange(location:0, length: baseStr.length), result: &rangeArr)
print("姓名 = \(str)" + ", 位置 = \(String(describing: arr.last))")
}
//知道 range 后就可以在对应的 range 上添加点击方法,并且添加 attribute
baseAttributeStr.addAttribute(NSAttributedString.Key.link, value:(用户 id, 或者其他数据), range: range)
网友评论