JavaScript如何提取字符串中带前置空格的@后的提及搜索词
React聊天应用@提及功能搜索词提取方案
原有方案问题
原实现使用的/@(\S+)/g正则存在两个核心缺陷:
- 无差别匹配所有位置的@字符,无法区分邮箱内嵌@、用户主动触发提及的@
- 全局匹配模式下默认取第一个命中结果,只要文本前方存在带@的内容(比如邮箱、之前已经输入完成的@提及),就会取错匹配项
优化实现方案
核心匹配规则调整为:仅匹配文本开头、或前置带空白字符的@,且只捕获用户当前正在输入的、位于输入内容末尾(或光标位置前)的@及后续文本,自动跳过其他位置的无效@。
匹配正则
const mentionRegex = /(?:^|\s)@(\S*)$/
正则各字段说明:
(?:^|\s):非捕获组,限定@的前置位置只能是文本开头、或者空白字符(空格/换行),直接排除邮箱这类@前后紧挨着非空白字符的场景,且不会把前置空格计入匹配结果@:匹配@字符本身(\S*):捕获@后0到多个非空白字符,兼容刚输入@还没输入搜索词的触发场景$:匹配文本末尾,保证只取用户最后正在输入的未完成@提及,不会命中前面已经输入完成的历史@内容
完整实现代码
/** * 提取@提及搜索词 * @param {string} inputText 输入框文本,若支持光标中间插入,传入光标位置前的文本子串即可 * @returns {string} 匹配到的提及搜索词,无有效匹配时返回空字符串 */ const extractMentionKeyword = (inputText) => { const matchRes = mentionRegex.exec(inputText.trimStart()); return matchRes ? `@${matchRes[1]}` : ''; }; // 场景验证 // 1. 包含邮箱的文本 const test1 = '我的邮箱是foo@bar.com @张'; console.log(extractMentionKeyword(test1)); // 输出 @张 // 2. 开头直接输入@ const test2 = '@李'; console.log(extractMentionKeyword(test2)); // 输出 @李 // 3. @后输入空格完成提及 const test3 = '@王 你好'; console.log(extractMentionKeyword(test3)); // 输出 空字符串,自动收起成员列表 // 4. 刚输入@还没打后续内容 const test4 = '大家好 @'; console.log(extractMentionKeyword(test4)); // 输出 @,正常触发成员列表弹出
可选扩展
如果需要支持用户在文本中间位置插入@的场景,不需要拿整个输入框文本做匹配,只需要截取从文本开头到当前光标位置的子串传入上述方法即可,就能精准识别用户当前输入位置的@触发,不会被光标后面的内容干扰。
内容的提问来源于stack exchange,提问作者cycero
相关产品推荐
相关产品推荐

