尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

从 STTweetLabel 学 iOS 链接识别:一条正则如何精准匹配 URL 而不错伤标点

从 STTweetLabel 学 iOS 链接识别:一条正则如何精准匹配 URL 而不错伤标点 从 STTweetLabel 学 iOS 链接识别一条正则如何精准匹配 URL 而不错伤标点【免费下载链接】STTweetLabelDeprecated - A UILabel with #hashtag handle and links tappable项目地址: https://gitcode.com/gh_mirrors/st/STTweetLabeliOS 链接识别是许多 App 的刚需像微博、Twitter 那样的文本里#话题、提及 和 URL 都要能自动高亮、点击响应。开源的 STTweetLabel 正是这样一个 UILabel 子类控件它把链接识别的核心押在一条精心设计的正则上。本文从 STTweetLabel 源码出发逐段拆解这条正则看看它是如何做到精准匹配 URL、不错伤末尾标点的。STTweetLabel 是什么让 UILabel 里的链接和话题可点击STTweetLabel 是一个基于 TextKit 的 iOS 开源控件2013 年发布适配 iOS 7官方已标记为 Deprecated但实现思路至今仍有学习价值。它把普通 UILabel 变成会识别热词的标签#iPhone、SebThiebaud、https://t.co/pQXDoiYA会被自动着色点击后通过 block 回调告诉你点到了什么。整个控件只有两个核心文件STTweetLabel.h 和 STTweetLabel.m。其中链接识别完全依赖一条正则。核心一条正则iOS 链接识别全靠它在 STTweetLabel.m 第 11 行定义了全文的主角(?i)\b((?:[a-z][\w-]:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-][.][a-z]{2,4}/)(?:[^\s()]|\(([^\s()]|(\([^\s()]\)))*\))(?:\(([^\s()]|(\([^\s()]\)))*\)|[^\s!()\[\]{};:.,?«»“”‘’]))别被吓到它其实由开头 主体 结尾三段拼装而成。拆解第 1 段正则如何识别 URL 开头URL 开头有三种合法形式带协议的完整形式[a-z][\w-]:(?:/{1,3}|[a-z0-9%])能匹配http://、https://、ftp://甚至tel:这类协议www 开头www\d{0,3}[.]兼容www.、www2.等变体裸域名加斜杠[a-z0-9.\-][.][a-z]{2,4}/匹配example.com/这种以斜杠收尾的地址。三种分支用|并列谁先命中用谁覆盖了日常 95% 以上的 URL 形态。拆解第 2 段URL 主体如何尽可能多吃字符主体部分(?:[^\s()]|\((...)\))允许两类字符反复出现一切非空白、非括号、非尖括号的字符——所以 URL 里的/、-、_、%、、?、都能被吞进去成对的圆括号片段——因为en.wikipedia.org/wiki/X_(disambiguation)这类地址确实带括号不能一棍子打死。拆解第 3 段末尾字符怎样做到不错伤标点这是整条正则最精彩的部分。URL 匹配的最后一拍规定最后一个字符要么是一个完整的平衡括号组要么绝对不能是标点。被排除的字符包括空白、!、( )、[ ]、{ }、; : 、. , ?甚至连中文里的«»“”‘’引号都考虑到了。于是当文本是访问 https://example.com。→ 匹配到https://example.com句号被干净利落地排除在外Check (https://example.com/a(1))!→ 因为括号成对https://example.com/a(1)被完整捕获末尾的!依然不沾边。这就是不错伤标点的秘密匹配结果的最后一个字符必须可信。从匹配到高亮STTweetLabel 的完整处理流程正则匹配只是第一步。在 determineLinks 方法 中STTweetLabel 用NSRegularExpression的enumerateMatchesInString遍历所有命中取出:之前的字符串作为协议protocol只有当协议命中validProtocols白名单默认http、https时链接才会被记录到_rangesOfHotWords随后在updateText中给这些 range 上色再靠getTouchedHotword把点击坐标换算成字符索引最终触发detectionBlock回调。顺带一提#话题 与 提及 的字符集扫描法链接走正则而#话题、提及走的是另一条路——字符集扫描。在 determineHotWords 方法 中它先用NSCharacterSet定义有效字符字母数字加下划线剔除常见标点遇到或#就向后连续吞字符直到撞上无效字符为止。还有一个贴心细节如果前面紧跟着字母数字比如邮箱sebastienworld.com会被直接跳过避免把邮箱误判成 提及。三行代码接入让链接识别立刻生效用法极其简单官方示例见 STViewController.mSTTweetLabel *label [[STTweetLabel alloc] initWithFrame:CGRectMake(10, 60, 300, 160)]; [label setText:Hi. This is a new tool for you! #iPhone https://t.co/pQXDoiYA]; [label setDetectionBlock:^(STTweetHotWord hotWord, NSString *string, NSString *protocol, NSRange range) { // 点击了话题 / 提及 / 链接在这里做你想做的事 }];一个UILabel子类 一条正则链接识别、话题高亮、点击回调全部搞定。写在最后STTweetLabel 用最朴素的方式回答了 iOS 链接识别的三个问题怎么匹配、怎么不错伤标点、怎么反馈点击。虽然项目已经 Deprecated现代开发大可直接使用UITextView的dataDetectorTypes但读懂这条正则的三段式设计你对 iOS 文本处理和正则边界的理解绝对会上一个台阶。✨【免费下载链接】STTweetLabelDeprecated - A UILabel with #hashtag handle and links tappable项目地址: https://gitcode.com/gh_mirrors/st/STTweetLabel创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表