如何用正则从含可变子域名的URL提取环境、域名及主机名
从可变子域名URL中提取环境、主机名和域名信息
需求是从带可变子域名的URL中提取三类信息:
- 环境标识:
qa或stage,无标识时为null - 主机名:固定的目标主机名(如示例中的
hostname) - 域名:顶级域名(如示例中的
com)
现有正则无法正确处理无环境标识的URL(比如https://example.hostname.com这类场景),需要优化正则以覆盖所有测试用例。
现有代码问题
原正则/.*(?<environment>(qa|stage*)).*\.(?<hostname>\w+)*\.(?<domain>\w+)$/存在以下问题:
- 强制要求环境标识存在,导致无环境的URL匹配失败
stage*写法错误,会匹配st加上任意数量的a,而非完整的stage- 匹配逻辑过于宽泛,容易捕获到URL中其他位置的非目标
qa/stage
优化后的解决方案
优化后的正则与代码
const regex = /^(?:https?:\/\/)?.*?(?:\.(?<environment>qa|stage))?.*?\.(?<hostname>\w+)\.(?<domain>\w+)$/; function extractInfoFromURL(url) { const match = url.match(regex); if (match) { // 将未捕获到环境标识的情况转为null return { environment: match.groups.environment ?? null, hostname: match.groups.hostname, domain: match.groups.domain }; } else { return null; // URL不符合格式 } } const testUrls = [ "https://example.test.qa.sub.hostname.com", "https://example.test.stage.coonect.hostname.com", "https://example.qa.hostname.com", "https://example.hostname.com", "https://example.stage.hostname.com", "https://ops-cert-stage-beta.apps.sub-test.minor.qa.test.sub.hostname.com", "https://ops-cert-qa-beta.apps.sub-test.minor.qa.test.sub.hostname.com", "https://ops-cert-qa.apps.sub-test.minor.qa.test.sub.hostname.com", "https://ops-cert-stage.apps.sub-test.minor.qa.test.sub.hostname.com" ]; testUrls.forEach((url, index) => { const result = extractInfoFromURL(url); if (result) { console.log(`Result for URL ${index + 1}:`, result); } else { console.log(`URL ${url} did not match the pattern.`); } });
正则逻辑解释
^(?:https?:\/\/)?:可选匹配URL开头的http://或https://,非捕获组避免干扰结果分组.*?:非贪婪匹配任意字符,防止过度占用后续匹配的内容(?:\.(?<environment>qa|stage))?:可选匹配以.开头的qa或stage作为环境标识,整个部分标记为可选(?),确保无环境的URL也能匹配.*?:再次非贪婪匹配中间的任意子域名部分\.(?<hostname>\w+)\.(?<domain>\w+)$:精确匹配主机名和顶级域名,锚定到URL结尾($)确保匹配的是域名的最后两段
测试结果说明
运行优化后的代码,所有测试URL都能正确匹配:
- 无环境标识的URL(如
https://example.hostname.com)返回environment: null - 包含
qa或stage的URL能正确提取对应的环境标识 - 主机名和域名在所有用例中都能准确捕获
内容的提问来源于stack exchange,提问作者Sumit Ridhal
相关产品推荐
相关产品推荐

