如何在 Javascript 中组合这两个正则表达式
How To Combine These 2 Regexp in Javascript
我写了一个 Javascript 例程,给定主机名或 URL,它 。
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 to try to advance my existing RegExp experience over the years, although I've never really understood lookbehinds and lookaheads (which might be useful here?), and then used the great tool at 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}))(?:[\/?#:]|$)
末尾的 (?:[\/?#]|$)
是匹配目标字符或字符串末尾的 non-capturing 组。
.*?
节俭地匹配任何东西。也就是说,它首先尝试匹配 root
捕获,然后是 (?:[\/?#]|$)
。每次失败,它都会吃掉一个字符并再次尝试,让你搜索 root
.
还有:
您可以将 \.\w{3,}|\.\w{2}
组合成 \.\w{2,}
。
您可以在 TLD 周围使用 non-capturing 组((?:...)
对比 (...)
。
最好使用 .*?
来获取协议,否则你可能会过度使用 globbing(使用贪婪的 .*
,传递 https://example.com/#://bar.com会 return bar.com
).
你不需要转义:
。在unicode模式下,那个转义实际上是一个语法错误。
结果为
const x = /^(?:.*?:\/\/)?.*?(?<root>[\w\-]*(?:\.\w{2,}|\.\w{2}\.\w{2}))(?:[\/?#:]|$)/
我实际上写了一个 RegExp 构建器,可以帮助您在 RegExp 学习之旅中走得更远...Here's your RegExp ported to compose-regexp
我写了一个 Javascript 例程,给定主机名或 URL,它
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 to try to advance my existing RegExp experience over the years, although I've never really understood lookbehinds and lookaheads (which might be useful here?), and then used the great tool at 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}))(?:[\/?#:]|$)
(?:[\/?#]|$)
是匹配目标字符或字符串末尾的 non-capturing 组。
.*?
节俭地匹配任何东西。也就是说,它首先尝试匹配 root
捕获,然后是 (?:[\/?#]|$)
。每次失败,它都会吃掉一个字符并再次尝试,让你搜索 root
.
还有:
您可以将
\.\w{3,}|\.\w{2}
组合成\.\w{2,}
。您可以在 TLD 周围使用 non-capturing 组(
(?:...)
对比(...)
。最好使用
.*?
来获取协议,否则你可能会过度使用 globbing(使用贪婪的.*
,传递 https://example.com/#://bar.com会 returnbar.com
).你不需要转义
:
。在unicode模式下,那个转义实际上是一个语法错误。
结果为
const x = /^(?:.*?:\/\/)?.*?(?<root>[\w\-]*(?:\.\w{2,}|\.\w{2}\.\w{2}))(?:[\/?#:]|$)/
我实际上写了一个 RegExp 构建器,可以帮助您在 RegExp 学习之旅中走得更远...Here's your RegExp ported to compose-regexp