【iOS】NSString&NSRange&NSCharacterSet

NSString&NSRange&NSCharacterSet

NSString

一、字符串查询/判断(最常用)

方法 作用 示例
length 获取字符串长度(UTF-16 编码的字符数) NSString *str = @"Hello"; NSInteger len = str.length; // 5
isEqualToString: 判断两个字符串内容是否完全相等(区分大小写) BOOL isSame = [@"abc" isEqualToString:@"ABC"]; // NO
hasPrefix: 判断字符串是否以指定前缀开头 BOOL isHttp = [@"https://xxx" hasPrefix:@"http"]; // YES
hasSuffix: 判断字符串是否以指定后缀结尾 BOOL isTxt = [@"test.txt" hasSuffix:@".txt"]; // YES
containsString: 判断字符串是否包含指定子串(iOS 8+) BOOL hasWorld = [@"Hello World" containsString:@"World"]; // YES
rangeOfString: 获取子串在字符串中的位置(返回 NSRange,未找到则 location=NSNotFound NSRange range = [@"Hello" rangeOfString:@"ll"]; // {2,2}(位置2,长度2)

二、字符串截取/拆分(高频)

方法 作用 示例
substringFromIndex: 从指定索引开始截取到末尾 NSString *sub = [@"HelloWorld" substringFromIndex:5]; // "World"
substringToIndex: 从开头截取到指定索引(不包含该索引) NSString *sub = [@"HelloWorld" substringToIndex:5]; // "Hello"
substringWithRange: 按指定范围(NSRange)截取子串 NSString *sub = [@"HelloWorld" substringWithRange:NSMakeRange(2,3)]; // "llo"
componentsSeparatedByString: 按指定分隔符拆分字符串为数组 NSArray *arr = [@"a,b,c" componentsSeparatedByString:@","]; // @[@"a",@"b",@"c"]
componentsSeparatedByCharactersInSet: 按指定字符集拆分(比如按空格/换行拆分) NSArray *arr = [@"a b\nc" componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; // @[@"a",@"b",@"c"]

三、字符串修改/转换(常用)B

方法 作用 示例
uppercaseString 转为全大写 NSString *upper = [@"hello" uppercaseString]; // "HELLO"
lowercaseString 转为全小写 NSString *lower = [@"HELLO" lowercaseString]; // "hello"
capitalizedString 首字母大写(每个单词首字母) NSString *cap = [@"hello world" capitalizedString]; // "Hello World"
stringByTrimmingCharactersInSet: 去除首尾指定字符(常用:去除空格/换行) NSString *trimmed = [@" hello \n" stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; // "hello"
stringByReplacingOccurrencesOfString:withString: 替换所有指定子串 NSString *newStr = [@"a-b-c" stringByReplacingOccurrencesOfString:@"-" withString:@"_"]; // "a_b_c"
stringByReplacingCharactersInRange:withString: 按范围替换子串 NSString *newStr = [@"Hello" stringByReplacingCharactersInRange:NSMakeRange(0,1) withString:@"h"]; // "hello"

四、路径/URL专用方法(iOS/macOS 开发核心)

方法 作用 示例
stringByAppendingPathComponent: 拼接路径片段,自动修正 / 分隔符 NSString *path = [@"/Documents" stringByAppendingPathComponent:@"test.txt"]; // "/Documents/test.txt"
lastPathComponent 获取路径最后一部分(文件名/文件夹名) NSString *name = [@"/Documents/test.txt" lastPathComponent]; // "test.txt"
stringByDeletingLastPathComponent 删除路径最后一部分(返回上级目录) NSString *dir = [@"/Documents/test.txt" stringByDeletingLastPathComponent]; // "/Documents"
pathExtension 获取文件扩展名 NSString *ext = [@"test.txt" pathExtension]; // "txt"
stringByDeletingPathExtension 删除文件扩展名 NSString *name = [@"test.txt" stringByDeletingPathExtension]; // "test"
stringByAddingPercentEncodingWithAllowedCharacters: URL编码(iOS 9+) NSString *encoded = [@"张三" stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];

五、数据转换(跨类型处理)

方法 作用 示例
integerValue/floatValue/doubleValue 转为对应数值类型 NSInteger num = [@"123" integerValue]; // 123
boolValue 转为布尔值("YES"/"1"→YES,"NO"/"0"→NO) BOOL b = [@"YES" boolValue]; // YES
dataUsingEncoding: 转为 NSData(指定编码,如 UTF-8) NSData *data = [@"hello" dataUsingEncoding:NSUTF8StringEncoding];
initWithData:encoding: NSData 初始化字符串 NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

补充:之前的「三个拼接方法对比表」(Markdown 版)

方法 核心定位 核心行为 性能 关键特性
stringByAppendingString: 纯字符串拼接工具 把第二个字符串原样拼接 到第一个末尾,无任何字符处理(比如不修正 /、不解析占位符) 最高(仅简单字符串拼接,无额外逻辑) 极简、无额外处理,仅做"字符拼接"
stringByAppendingPathComponent: 文件路径专用拼接工具 拼接路径片段,自动修正路径分隔符 / : 1. 原路径末尾有 / → 自动去重 2. 原路径无 / → 自动补充 3. 适配 iOS/macOS 路径规范 中等(多了分隔符校验逻辑) 专为文件路径设计,保证路径合法性
stringWithFormat: 格式化字符串生成工具 解析带占位符(%@/%d 等)的模板字符串,将参数按格式填充生成新字符串 最低(需解析占位符、类型转换) 支持多参数、多类型(字符串/数字等)拼接,核心是"格式化"

NSRange

一、NSRange 核心定义

NSRange 是 Foundation 框架提供的结构体(非类/方法),专门用于描述"起始位置 + 长度"的范围,是处理字符串、数组等有序集合的基础工具。

核心信息 具体说明
结构体声明 typedef struct _NSRange { NSUInteger location; // 起始位置(索引,从 0 开始) NSUInteger length; // 范围长度(包含的元素个数)} NSRange;
关键常量 NSNotFound:表示"未找到"(等价于 NSUIntegerMax,赋值给 location 时代表范围无效)
构造方式 1. 直接赋值:NSRange range = {2, 3};(位置2,长度3) 2. 推荐方法:NSRange range = NSMakeRange(2, 3);(更易读)

二、NSRange 核心使用场景

NSRange 主要用于有序集合(字符串/数组) 的"查找、截取、替换"操作,是 Objective-C 开发中高频使用的工具,核心场景如下:

使用场景 作用说明 关联类/方法
字符串查找 获取子串在父字符串中的位置和长度 NSStringrangeOfString: 方法
字符串截取 按指定范围截取子串 NSStringsubstringWithRange: 方法
字符串替换 按指定范围替换部分字符串 NSStringstringByReplacingCharactersInRange:withString: 方法
数组操作 截取数组的指定范围元素 NSArraysubarrayWithRange: 方法
文本控件操作 定位文本输入框的选中范围 UITextField/UITextViewselectedRange 属性

三、NSRange 与其他类型的转换

NSRange 是结构体,无法直接和字符串/数字转换,但可通过工具方法实现"范围 ↔ 可读字符串"的转换,方便调试和日志输出:

转换方向 方法/示例 说明
NSRange → NSString(调试用) NSString *rangeStr = NSStringFromRange(range); 将范围转为字符串(如 {2,3}@"{2,3}"
NSString → NSRange NSRange range = NSRangeFromString(@"{2,3}"); 将字符串转回 NSRange(仅用于调试,生产环境慎用)
NSRange ↔ 索引区间(手动计算) 示例: // 已知结束索引,计算 NSRange NSUInteger start = 2; NSUInteger end = 5; NSRange range = NSMakeRange(start, end - start); // {2,3} 实际开发中常需通过"起始索引+结束索引"计算范围

四、NSRange 实战使用示例

示例1:字符串查找(最常用)

Objective-C 复制代码
// 查找子串位置
NSString *parentStr = @"Hello World";
NSRange range = [parentStr rangeOfString:@"World"];

// 判断是否找到
if (range.location != NSNotFound) {
    NSLog(@"子串位置:%ld,长度:%ld", range.location, range.length); // 输出:6,5
    // 转为字符串方便调试
    NSString *rangeStr = NSStringFromRange(range);
    NSLog(@"范围字符串:%@", rangeStr); // 输出:{6,5}
} else {
    NSLog(@"未找到子串");
}

示例2:字符串截取

Objective-C 复制代码
NSString *parentStr = @"Hello World";
// 截取 "llo"(位置2,长度3)
NSRange range = NSMakeRange(2, 3);
NSString *subStr = [parentStr substringWithRange:range];
NSLog(@"截取结果:%@", subStr); // 输出:llo

示例3:字符串替换

Objective-C 复制代码
NSString *parentStr = @"Hello World";
// 将 "World" 替换为 "iOS"
NSRange range = [parentStr rangeOfString:@"World"];
if (range.location != NSNotFound) {
    NSString *newStr = [parentStr stringByReplacingCharactersInRange:range withString:@"iOS"];
    NSLog(@"替换结果:%@", newStr); // 输出:Hello iOS
}

示例4:数组范围操作

Objective-C 复制代码
NSArray *array = @[@"a", @"b", @"c", @"d", @"e"];
// 截取索引1-3的元素(位置1,长度3)
NSRange range = NSMakeRange(1, 3);
NSArray *subArray = [array subarrayWithRange:range];
NSLog(@"子数组:%@", subArray); // 输出:(b, c, d)

示例5:处理"未找到"场景

Objective-C 复制代码
NSString *parentStr = @"Hello World";
NSRange range = [parentStr rangeOfString:@"Android"];
if (range.location == NSNotFound) {
    NSLog(@"未找到子串 Android");
}

五、NSRange 常见坑点

坑点 避坑方法
索引越界 使用前检查 location 是否小于集合长度,location + length 是否超过集合长度
混淆"结束索引"和"长度" 记住:length = 结束索引 - 起始索引,而非直接用结束索引作为 length
忽略 NSNotFound 判断 所有通过 rangeOfString: 获取的 NSRange,必须先判断 location != NSNotFound 再使用

总结

  1. NSRange 是描述"起始位置+长度"的结构体,核心用于字符串/数组的查找、截取、替换操作;
  2. 构造 NSRange 优先用 NSMakeRange(),判断是否找到需检查 location != NSNotFound
  3. 开发中常需手动计算范围(长度=结束索引-起始索引),避免索引越界和长度错误;
  4. NSStringFromRange()/NSRangeFromString() 仅用于调试,生产环境慎用。

你希望我把 NSCharacterSet 的核心知识点(定义、使用场景、使用方法、注意事项)整理成结构化、易理解的 Markdown 内容,方便你快速掌握和查阅,对吧?NSCharacterSet 是 Objective-C 中处理字符过滤/校验/拆分的核心工具,下面我按「核心定义→使用场景→使用方法→注意事项」的逻辑,用清晰的表格+示例呈现:

NSCharacterSet

系统预定义 NSCharacterSet 字符对照表

类属性 包含的字符类型/范围
controlCharacterSet ASCII 控制字符(0x00~0x1F、0x7F):换行\n、制表符\t、退格\b、空字符\0等不可打印字符
whitespaceCharacterSet 水平空白字符:空格( )、制表符(\t)、垂直制表符等(不含换行/回车)
whitespaceAndNewlineCharacterSet 水平空白字符 + 换行符(\n)、回车符(\r
decimalDigitCharacterSet 十进制数字:0-9(Unicode 0x30~0x39)
letterCharacterSet 所有字母(大小写):A-Z、a-z + 多语言字母(é、ü、ñ 等)
lowercaseLetterCharacterSet 小写字母:a-z + 多语言小写字母(è、ü 等)
uppercaseLetterCharacterSet 大写字母:A-Z + 多语言大写字母(È、Ü 等)
nonBaseCharacterSet 附加符号:重音符号(̀́)、波浪符(̃)等(需和基础字符组合显示)
alphanumericCharacterSet 字母(全语言) + 十进制数字(0-9)
decomposableCharacterSet 可分解组合字符:é(e+重音)、ñ(n+~)、æ(a+e)等
illegalCharacterSet 系统非法字符:不可打印 Unicode 字符、文件路径非法字符、未定义编码字符
punctuationCharacterSet 全类型标点:逗号、句号、问号、感叹号、破折号、括号、引号、顿号、逗号等
capitalizedLetterCharacterSet 首字母大写字符(Title Case):如 Hello 中的 H、World 中的 W
symbolCharacterSet 各类符号:$、%、&、*、+、_、#、@、¥、%、^、& 等
newlineCharacterSet 换行相关字符:换行符(\n)、回车符(\r)、\r\n 组合

一、NSCharacterSet 核心定义

NSCharacterSet(不可变)/NSMutableCharacterSet(可变)是 Foundation 框架中用于描述一组字符规则的集合类,核心作用是快速过滤、拆分、校验字符串中的字符,替代手动遍历字符判断,效率更高、代码更简洁。

核心信息 具体说明
类特性 - NSCharacterSet:不可变,创建后无法修改包含的字符规则 - NSMutableCharacterSet:可变子类,可动态添加/删除字符规则
底层逻辑 并非存储具体字符列表,而是通过"字符范围/规则"描述字符集合,判断字符是否属于集合时效率为 O(1)
核心价值 避免手动遍历字符串判断字符类型(如"是否是数字""是否是空格"),简化代码且性能更优

二、核心使用场景(开发高频)

使用场景 具体说明 关联 NSString 方法
去除字符串首尾指定字符 过滤开头/结尾的空格、换行、特殊符号(最常用) stringByTrimmingCharactersInSet:
按字符规则拆分字符串 按"任意空白/换行""任意数字"等规则拆分字符串 componentsSeparatedByCharactersInSet:
过滤字符串中的指定字符 保留/删除字符串中属于某字符集的字符(如仅保留数字) 结合 componentsSeparatedByCharactersInSet: + 拼接实现
校验字符/字符串类型 判断字符是否是数字/字母、字符串是否仅含指定字符(如用户名校验) characterIsMember:
URL 编码/解码 过滤 URL 中非法字符,仅保留允许的字符 stringByAddingPercentEncodingWithAllowedCharacters:

三、使用方法(分场景示例)

3.1 基础:使用系统预定义字符集(优先选择)

苹果内置了常用字符集,无需自定义即可直接使用,覆盖80%的开发场景:

Objective-C 复制代码
// 1. 去除字符串首尾的空格+换行(最常用)
NSString *input = @"  Hello World  \n\r";
NSCharacterSet *spaceSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];
NSString *trimmed = [input stringByTrimmingCharactersInSet:spaceSet];
NSLog(@"处理后:%@", trimmed); // 输出:Hello World

// 2. 判断字符是否是数字
unichar ch = '8';
NSCharacterSet *digitSet = [NSCharacterSet decimalDigitCharacterSet];
BOOL isDigit = [digitSet characterIsMember:ch]; // YES

3.2 进阶:自定义字符集(NSMutableCharacterSet)

需过滤特殊字符(如仅允许字母/数字/中文)时,用可变字符集自定义:

Objective-C 复制代码
// 需求:过滤昵称中的特殊符号,仅保留字母、数字、中文、下划线
NSString *nickname = @"张三_#123$";

// 1. 创建可变字符集,初始包含字母+数字
NSMutableCharacterSet *allowedSet = [NSMutableCharacterSet alphanumericCharacterSet];
// 2. 添加中文(Unicode 范围:0x4E00 ~ 0x9FFF)
[allowedSet addCharactersInRange:NSMakeRange(0x4E00, 0x9FFF - 0x4E00 + 1)];
// 3. 添加下划线
[allowedSet addCharactersInString:@"_"];

// 4. 获取"不允许的字符集"(反集)
NSCharacterSet *forbiddenSet = [allowedSet invertedSet];
// 5. 拆分并拼接,过滤不允许的字符
NSString *cleanNickname = [[nickname componentsSeparatedByCharactersInSet:forbiddenSet] componentsJoinedByString:@""];
NSLog(@"清理后:%@", cleanNickname); // 输出:张三_123

3.3 高级:按字符集拆分字符串

Objective-C 复制代码
// 需求:拆分包含空格、制表符、换行的文本
NSString *text = @"a b\tc\nd";
NSCharacterSet *splitSet = [NSCharacterSet whitespaceCharacterSet];
// 按任意空白字符拆分
NSArray *arr = [text componentsSeparatedByCharactersInSet:splitSet];
// 过滤拆分后的空字符串(避免出现@""元素)
arr = [arr filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF != ''"]];
NSLog(@"拆分结果:%@", arr); // 输出:(a, b, c, d)

四、注意事项(避坑核心)

注意点 具体说明 避坑方法
混淆空白字符集 whitespaceCharacterSet 仅包含空格/制表符,whitespaceAndNewlineCharacterSet 包含空格+换行,去除换行需用后者 去除首尾空白+换行时,优先用 whitespaceAndNewlineCharacterSet
中文字符集范围错误 中文 Unicode 范围是 0x4E00 ~ 0x9FFF,计算长度需 0x9FFF - 0x4E00 + 1 自定义中文字符集时,严格按上述范围添加
拆分字符串后出现空元素 按字符集拆分时,连续分隔符会生成空字符串 拆分后用谓词过滤空字符串(SELF != ''
直接用 characterIsMember: 判断多字符字符串 characterIsMember: 仅接收单个 unichar 字符,无法直接判断字符串 遍历字符串的每个字符,逐一调用 characterIsMember:
误用不可变字符集修改 NSCharacterSet 不可变,调用 addCharactersInString: 会编译报错 需修改字符集时,使用 NSMutableCharacterSet
URL 编码字符集错误 手动自定义 URL 允许字符集易出错,优先用系统预定义的 URLQueryAllowedCharacterSet 避免手动拼接 URL 允许字符,使用 [NSCharacterSet URLQueryAllowedCharacterSet]

总结

  1. 核心定位NSCharacterSet 是字符过滤/校验的高效工具,优先使用系统预定义字符集,减少自定义成本;
  2. 高频用法whitespaceAndNewlineCharacterSet + stringByTrimmingCharactersInSet: 去除首尾空白,是开发中最常用的组合;
  3. 关键技巧 :通过 invertedSet 获取字符集反集,可快速实现"过滤非指定字符";
  4. 避坑核心:区分空白字符集、正确设置中文字符 Unicode 范围、拆分后过滤空元素。
相关推荐
h-189-53-6712072 小时前
2026(原创)Guideline 4.3(a) - Design - Spam苹果上架iOS审核被拒AppStore卡审解决办法思路
ios
杨武博4 小时前
ios 启动图不生效问题
ios
2501_915106325 小时前
常见 iOS 抓包工具的使用方式与组合思路
android·ios·小程序·https·uni-app·iphone·webview
SY_FC5 小时前
niapp开发的 H5 被app嵌套,H5调用ios和安卓方法
android·ios·cocoa
TheNextByte16 小时前
如何将Mac上的联系人同步到 iPhone?
macos·cocoa·iphone
我不是8神15 小时前
gin与gorm框架知识点总结
ios·iphone·gin
皇上o_O1 天前
深入理解 Swift Concurrency:从 async/await 到隔离域
ios
CocoaKier1 天前
1月12日最新用户隐私保护政策出炉,政策解读
ios
Mr -老鬼1 天前
移动端跨平台适配技术框架:从发展到展望
android·ios·小程序·uni-app