React Native中解构Regex分组遇Undefined错误,如何使用命名分组?
React Native正则命名分组解构报错及访问问题
问题现象
在React Native中解析带命名分组的正则表达式时,尝试解构match.groups到变量时触发错误:
TypeError: Cannot read property 'familyName' of undefined, js engine: hermes
对应代码片段:
const parseCode = data => { const payload = {}; for (const match of data.matchAll(rgx)) { const {familyName, givenName, birthday} = match.groups; console.log(`familyName: ${familyName} givenName:${givenName} birthday: ${birthday}`); } };
补充测试信息
正则定义了FamilyName、GivenName、Birthday等命名分组,在普通JavaScript环境测试时,仅通过索引访问匹配值的方式有效,使用match.groups?.FamilyName这类命名分组访问会返回undefined:
测试代码:
const data= "%SPECIMEN,$TESTTHREE^910 FIRST ST$ALBERTA AB V8W 3Y8^?;19900403?" const rgx = /^%(?<track1>((?<FamilyName>\b[A-Z0-9\s.\-',]+)\$(?<GivenName>(?:[A-Z0-9\s.\-'])+)){0,35}\^((?<AddressLine1>\b[A-Z0-9\s.\-',]+)\$(?<AddressLine2>(?:[A-Z0-9\s.\-'])+)){0,29}\^)\?;(?<track2>(?<Birthday>\d{0,8}))\?/g; // 索引访问有效 const matches = data.matchAll(rgx); let output1 = {}; for (const match of matches) { output1.surname = match[4]; output1.givenName = match[5]; output1.birthday = match[14]; } console.log("output1") console.log(output1); // 命名分组访问返回undefined const output2 = Array.from(data.matchAll(rgx), ({groups}) => ({ surname: groups?.FamilyName?.replace(/,\s*$/, '') || null, givenName: groups?.GivenName || null, birthday: groups?.Birthday || null, })); console.log('output2'); console.log(output2);
解决方案及关键调整
1. 修正大小写不匹配问题
JavaScript正则的命名分组大小写敏感,你的正则中定义的是FamilyName、GivenName、Birthday,但解构时用的是小写开头的familyName等,这是导致取值undefined的直接原因之一。
2. 处理正则结构与Hermes兼容性
你的正则中,命名分组被包裹在{0,35}这类重复量词内部,Hermes引擎对这种嵌套重复的命名分组支持存在局限性——重复匹配时,只有最后一次匹配结果会被保留,甚至可能直接丢失分组捕获结果。可以简化正则结构,移除不必要的重复量词(测试数据中该部分仅出现一次):
const rgx = /^%(?<track1>(?<FamilyName>\b[A-Z0-9\s.\-',]+)\$(?<GivenName>(?:[A-Z0-9\s.\-'])+)\^((?<AddressLine1>\b[A-Z0-9\s.\-',]+)\$(?<AddressLine2>(?:[A-Z0-9\s.\-'])+))\^)\?;(?<track2>(?<Birthday>\d{0,8}))\?/g;
3. 添加空值防御
在解构时增加空值判断,避免match.groups为undefined时触发报错:
const parseCode = data => { const payload = {}; for (const match of data.matchAll(rgx)) { // 匹配正则分组名,同时用空对象兜底防止groups为undefined const {FamilyName: familyName, GivenName: givenName, Birthday: birthday} = match.groups || {}; console.log(`familyName: ${familyName} givenName:${givenName} birthday: ${birthday}`); } };
内容的提问来源于stack exchange,提问作者JarochoEngineer
相关产品推荐
相关产品推荐

