我写了一个 Javascript 例程,给定主机名或 URL,它 finds the root domain .
function getRootDomain(s){
var sResult = ''
try {
sResult = s.match(/^(?:.*\:\/?\/)?(?<domain>[\w\-\.]*)/).groups.domain
.match(/(?<root>[\w\-]*(\.\w{3,}|\.\w{2}|\.\w{2}\.\w{2}))$/).groups.root;
} catch(ignore) {}
return sResult;
}
将两个正则表达式规则合并为一个规则的技巧是什么?
我用了this tutorial多年来尝试提升我现有的 RegExp 经验,尽管我从来没有真正理解后视和先行(这在这里可能有用吗?),然后使用了 RegEx101.com 上的伟大工具。用于反复试验。我尝试的是坚持 <root>
之后的内容替换 <domain>
之后的内容,以及它的变体,但都失败了。
与 RegEx101 等工具一起使用的测试集可能是:
https://test.com:8080/?id=4&re=3
https://test-test.com:8080/?id=4&re=3
https://data.test.com:8080/?id=4&re=3
https://data.test.com/?id=4&re=3
https://data.test.com/
https://data.test.com#testing
https://data.test.com/#testing
https://data.test.com:8080/#testing
https://data.test.com:8080#testing
https://data.tester.com/
https://data-test.test.com/
https://test.com
https://test.com#testing
https://test.com/
https://test.am/?id=4
https://test.com?id=3&re=3
https://test.com/?id=3&re=3
https://megatest.com/?id=3&re=3
test.com
data.test.co.uk
test.co
data.test.com
data.tester-test.com
data-test.tester-test.com
tester-test.com
about:blank
最佳答案
第二个正则表达式使用 $
断言只匹配 .domain
的末尾捕获。
但是,第一个 RegExp 在域之后停止匹配(当它遇到 /
、?
、#
、:
或字符串结尾(如果没有路径)时,查询字符串或哈希部分。所以你不能只重用 $
断言,它在某些情况下会失败。
要合并这两个部分,您可以替换 domain
用这个捕获:
.*?(?<root>[\w\-]*(\.\w{3,}|\.\w{2}|\.\w{2}\.\w{2}))(?:[\/?#:]|$)
(?:[\/?#]|$)
最后是匹配目标字符或字符串结尾的非捕获组。
.*?
节俭地匹配任何东西。也就是说,它首先尝试匹配 root
捕获后跟 (?:[\/?#]|$)
.每次失败,它都会吃掉一个字符并再次尝试,让你搜索 root
。 .
还有:
你可以组合
\.\w{3,}|\.\w{2}
进入刚刚\.\w{2,}
.您可以在 TLD 周围使用非捕获组(
(?:...)
对比(...)
。最好用
.*?
获取协议(protocol),否则你可能会过度使用 globbing(使用贪婪的.*
,传递 https://example.com/#://bar.com 将返回bar.com
)。您不需要转义
:
.在 unicode 模式下,这种转义实际上是一个语法错误。
结果为
const x = /^(?:.*?:\/\/)?.*?(?<root>[\w\-]*(?:\.\w{2,}|\.\w{2}\.\w{2}))(?:[\/?#:]|$)/
我实际上写了一个 RegExp 构建器,可以帮助您在 RegExp 学习之旅中走得更远... Here's your RegExp ported to compose-regexp
关于javascript - 如何在 Javascript 中组合这两个正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72091640/