正则表达式无法匹配中间分组,求解原因及解决方法
正则匹配TypeScript联合类型时仅捕获最后一个分组的问题
我需要捕获以下TypeScript类型定义中的字符串:
// 需捕获"Closed"、"RequireApplication"、"Open" export type RegistrationMode = "Closed" | "RequireApplication" | "Open"; // 需捕获"All"、"Comments"……"Url" export type SearchType = | "All" | "Comments" | "Posts" | "Communities" | "Users" | "Url";
但我编写的匹配器export type \w+ =(\S+)?(?:\s+\| (\S+))*;仅能匹配最后一个分组,遗漏了中间的分组,请问问题出在哪里?
问题原因
正则里的重复捕获组(比如(?:\s+\| (\S+))*)只会保留最后一次匹配的结果,之前的匹配会被覆盖。因为当分组被*或+这类量词重复时,正则引擎不会存储每一次的匹配值,只会不断更新为最后一次的匹配内容。
解决方案
要捕获所有目标字符串,有两种实用思路:
先抓整体再拆细节
先写正则匹配整个类型定义块,把所有联合项的内容作为一个整体捕获,再用另一个正则提取其中的每个字符串。
示例主正则:export type \w+ =(?:\s*\|?\s*\S+)+;拿到整体内容后,再用
"([^"]+)"全局匹配,就能提取每个引号内的文本。利用捕获组迭代特性
像JavaScript的matchAll这类API支持迭代获取所有捕获组的匹配结果,可以用如下正则配合使用:export type \w+ =(?:\s*\|?\s*"([^"]+)")+;遍历
matchAll返回的结果,收集每个结果里分组1的内容,就能得到所有目标字符串。
针对场景优化的正则
如果你的环境支持正向预查和全局匹配,推荐用这个正则直接捕获所有目标:
(?<=export type \w+ =(?:\s*\|?\s*))"([^"]+)"
它通过正向预查定位到类型定义的范围,然后全局匹配所有引号内的字符串,每个匹配的分组1就是你需要的内容。
内容的提问来源于stack exchange,提问作者Some Noob Student
相关产品推荐
相关产品推荐

