1、编写逻辑
使用分类(Category)的方法拓展NSString,本文使用NSString (Markdown),NSString的分类来编写一个通用方法,使用正则表达式匹配字符串实现去除特殊字符,并自定义文字属性。
在接入AI大模型后,返回的字符串会带有特殊字符用于做文字处理,下面代码简单进行了文字处理展示。
2、代码实现
1、NSString+Markdown.h
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface NSString (Markdown)
- (NSAttributedString *)attributedStringFromMarkdown;
@end
NS_ASSUME_NONNULL_END
2、NSString+Markdown.m
文中做了处理 ### 与 **加粗文本** 的处理,可根据需求进行拓展
#import "NSString+Markdown.h"
static NSRegularExpression *_headerRegex;
static NSRegularExpression *_boldRegex;
static dispatch_once_t onceToken;
@implementation NSString (Markdown)
- (NSAttributedString *)attributedStringFromMarkdown {
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:self];
// 设置默认字体,做自适应高度时,必须要设置默认字体
UIFont *defaultFont = [UIFont systemFontOfSize:20];
[attributedString addAttribute:NSFontAttributeName value:defaultFont range:NSMakeRange(0, attributedString.length)];
// 一次性初始化正则表达式
dispatch_once(&onceToken, ^{
NSError *error;
// 匹配 ### 标题
_headerRegex = [NSRegularExpression regularExpressionWithPattern:@"^###\\s*(.*?)\\s*(?=\n)"
options:NSRegularExpressionAnchorsMatchLines
error:&error];
if (error) {
NSLog(@"### 正则表达式初始化失败: %@", error.localizedDescription);
}
// 匹配 **加粗文本**
_boldRegex = [NSRegularExpression regularExpressionWithPattern:@"\\*\\*(.*?)\\*\\*"
options:0
error:&error];
if (error) {
NSLog(@"** 正则表达式初始化失败: %@", error.localizedDescription);
}
});
// 处理 "### 标题" 的加粗,并去掉 "###"
NSArray *headerMatches = [_headerRegex matchesInString:attributedString.string
options:0
range:NSMakeRange(0, attributedString.length)];
for (NSTextCheckingResult *match in [headerMatches reverseObjectEnumerator]) {
NSRange fullMatchRange = match.range; // 包含 ### 的完整匹配范围
NSRange contentRange = [match rangeAtIndex:1]; // 实际要加粗的内容
if (contentRange.location != NSNotFound) {
// 1️⃣ 应用加粗样式
[attributedString addAttributes:@{
NSFontAttributeName: [UIFont boldSystemFontOfSize:20]
} range:contentRange];
// 2️⃣ 替换 "### 标题" 只保留标题文本
NSString *content = [attributedString.string substringWithRange:contentRange];
[attributedString replaceCharactersInRange:fullMatchRange withString:content];
// 3️⃣重新获取新文本的位置
NSRange newRange = NSMakeRange(fullMatchRange.location, content.length);
// 重新加粗
[attributedString addAttributes:@{
NSFontAttributeName: [UIFont boldSystemFontOfSize:20]
} range:newRange];
}
}
// 处理 "**加粗文本**" 的加粗,并去掉 "**"
NSArray *boldMatches = [_boldRegex matchesInString:attributedString.string
options:0
range:NSMakeRange(0, attributedString.length)];
for (NSTextCheckingResult *match in [boldMatches reverseObjectEnumerator]) {
NSRange fullMatchRange = match.range; // 包含 ** 的完整匹配范围
NSRange contentRange = [match rangeAtIndex:1]; // 实际要加粗的内容
if (contentRange.location != NSNotFound) {
// 1️⃣ 应用加粗样式
[attributedString addAttributes:@{
NSFontAttributeName: [UIFont boldSystemFontOfSize:20]
} range:contentRange];
// 2️⃣ 替换 "**加粗文本**" 只保留加粗文本
NSString *content = [attributedString.string substringWithRange:contentRange];
[attributedString replaceCharactersInRange:fullMatchRange withString:content];
// 3️⃣重新获取新文本的位置
NSRange newRange = NSMakeRange(fullMatchRange.location, content.length);
// 重新加粗
[attributedString addAttributes:@{
NSFontAttributeName: [UIFont boldSystemFontOfSize:20]
} range:newRange];
}
}
return attributedString;
}
@end
3、调用方法
NSString *text = [message.text attributedStringFromMarkdown].string;