使用正则表达式处理邮箱数组提取姓氏生成新数组的问题
问题:从邮箱数组中提取姓氏并生成新数组
我有一个邮箱地址数组:
var emails = ['first.last@email.com', 'frst.lst@email.com', 'test.name@email.com']
我编写了一个正则表达式用于从邮箱中提取姓氏:
var re = /(?<=[.]).*(?=[\@])/g; // 从邮箱中提取姓氏
我希望提取这些姓氏并生成一个新数组,预期结果如下:
['last', 'lst', 'name']
我尝试了以下代码,但它根本无法提取姓氏,只是输出了第一个和最后一个邮箱地址:
function onEdit() { var re = /(?<=[.]).*(?=[\@])/g; var emails = ['first.last@email.com', 'frst.lst@email.com', 'test.name@email.com'] const matchVal = emails.filter(value => re.test(value)); Logger.log(matchVal); } // 上述函数的输出结果 // [first.last@email.com, test.name@email.com]
请问如何实现需求?谢谢!
解决方案
问题分析
当前代码存在两个核心问题:
filter方法的作用是过滤出符合条件的原数组元素,而非提取匹配的子串,因此返回的是原邮箱地址而非目标姓氏。- 正则加了全局标志
g后,re.test()会维护一个lastIndex指针,导致对数组元素的检测交替成功/失败,最终只输出部分原邮箱地址。
可行实现方式
方法1:基于正则的map+match方案
去掉正则的全局标志g,用map遍历数组提取匹配内容:
function onEdit() { var re = /(?<=[.]).*(?=[\@])/; // 移除全局标志g var emails = ['first.last@email.com', 'frst.lst@email.com', 'test.name@email.com']; const lastNames = emails.map(email => { const match = email.match(re); return match ? match[0] : ''; // 兼容可能的不匹配场景 }); Logger.log(lastNames); // 输出 ['last', 'lst', 'name'] }
方法2:字符串分割方案(更简洁)
无需正则,通过两次split直接拆分出姓氏:
function onEdit() { var emails = ['first.last@email.com', 'frst.lst@email.com', 'test.name@email.com']; const lastNames = emails.map(email => { const localPart = email.split('@')[0]; // 提取@符号前的部分,如first.last return localPart.split('.').pop(); // 按.拆分后取最后一段 }); Logger.log(lastNames); // 输出 ['last', 'lst', 'name'] }
方法3:保留全局标志的exec方案
若必须保留全局标志,每次匹配前重置lastIndex即可:
function onEdit() { var re = /(?<=[.]).*(?=[\@])/g; var emails = ['first.last@email.com', 'frst.lst@email.com', 'test.name@email.com']; const lastNames = emails.map(email => { re.lastIndex = 0; // 重置正则的匹配指针 const match = re.exec(email); return match ? match[0] : ''; }); Logger.log(lastNames); // 输出 ['last', 'lst', 'name'] }
内容的提问来源于stack exchange,提问作者hunter21188
相关产品推荐
相关产品推荐

