首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用于匹配顶级域不是.com、.net、.org、.info、.edu、.gov或.ca的url的Regex。

用于匹配顶级域不是.com、.net、.org、.info、.edu、.gov或.ca的url的Regex。
EN

Stack Overflow用户
提问于 2021-11-09 16:32:28
回答 3查看 842关注 0票数 0

我正在寻找regex来匹配来自.com、.net、.org、.info、.edu、.gov或.ca域的整个urls。TLD列表可能会随着时间的推移而增加,但这是一个好的开始。

这些将匹配:

这些不匹配:

对于一些背景,我希望使用Exchange的表达式来过滤包含异常/国际链接的入站电子邮件,在我们的例子中,这些链接几乎是100%的钓鱼或垃圾邮件。我们是一家小企业,只为当地客户提供服务,通常所有的供应商都是北美地区的。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-11-17 02:56:22

回答

棘手的那个。这里是:

代码语言:javascript
复制
/https?:\/\/(?![\w.-]+\.(?:com|edu|gov|ca|net|org|info)[^\w.-])\S*/gi

适用于下面列出的所有用例:

这些不匹配:

代码语言:javascript
复制
https://www.organization.org/    
https://some-server.example.ca/home    
https://www.complete.com/index.php   
https://www.example.com   
https://www.example.com/?url=junk.xyz   
https://www.freddy.dana.comealong.com/   
http://www.example.info:8181 
https://some_server.example.ca/home.html   
https://www.complete.com/index.php   
https://www.organization.org/   

这些将匹配:

代码语言:javascript
复制
https://www.spammy.spammer.comealong.cop/    
https://spam.caught.cat/home/away/now/index.htm    
https://www.complete.xyz/index.php?com=seww    
https://www.example.abc/?spam=yes&spammer=yep&from=me.com    
https://www.example.ru/spammy/spammer/index.php    
https://www.com_server.ru/?url=beep.gov&para=HaHaGotYou    
https://www.example.ru    
https://www.example.ru/home.html.com    
http://www.example.xyz/index.php    
https://some-server.example.co.uk/home    

顶级组不匹配,底部组匹配所有,因此您可以发送到/dev/cornfield

在下面的组中,请注意有一些包含.com的URL参数,但是我的假设是,您也想把它们吹走,所以正则表达式在定义TLD出现的方式和位置方面非常狭窄。

还有像www.complete.xyz或"example.abc/spam.com“这样的网址,显然应该选择它们。详情如下:

这里有一个指向正则笔的链接:https://regexr.com/69vce

教程:

代码语言:javascript
复制
/https?:\/\/(?![\w.-]+\.(?:com|edu|gov|ca|net|org|info)[^\w.-])\S*/gi

从obv https?:\/\/开始,但我们立即进入负前瞻性(?!

对于非选定的URL,我们希望基于TLD (仅使用TLD),参数中不存在.com,也不跳过像www.complete.abc这样的名称。

因此,负前瞻的第一部分是[\w.-]+\.,因此我们只计算括号中的字母数和- .,其中有一对多的字母数字和+,因为它们可能在TLD之前,然后是一个强制转义期\.,这就是我们如何“锁定”TLD的方法。

注1:在括号内,当括号内时,不需要转义句号。这是一个文字句点,而不是通配符。

注2:\w包含下划线``_,它不是合法的域字符,但我们忽略了,因为我们不需要具体验证所提供的域名。

接下来是一个非捕获组,ORed |列表中的TL域不匹配,然后[^\w.-]是如何阻止像www.complete.xyz这样的名称的。这将拒绝任何TLD字母,如果后面跟着任何合法域名char:字母编号,期间连字符。请注意,连字符-是组中的最后一个,因为如果是的话,假设是[^-\w.],这将是regex的某些实现中的一个错误,因为连字符在其他方面用于a-z之类的系列。

最后,\S*意味着匹配除空白字符之外的所有内容。因此,如果负查找没有拒绝此行匹配,那么我们将返回到http://并获取整个URL的其余部分。

现在,这可能有点宽泛,但既然我认为你只是在破坏它们,那应该是好的。如果您选择它们以供进一步使用,那么您可能希望使用一些更有选择性的东西,比如[\w.:%&?~=/-]*。这包括句点、端口冒号、= & ?表示params、%用于URL转义等等。连字符是最后一个。

当然,在最后,全局和大小写不敏感的/gi

票数 1
EN

Stack Overflow用户

发布于 2021-11-17 03:07:50

为了匹配整个URL..。

注意,此实现试图根据匹配不寻常URL的用法覆盖其他元素:

  • 任何可能未知安全向量的模式(例如ftpldap)
  • 包含基本auth用户名和密码
  • IPv6 IP地址
  • 指定端口号(例如https://www.example.com:8080/)
  • 没有路径,即只有主机名/ IP地址
  • 查询字符串
  • 片段

我不知道"Exchange“所使用的确切正则表达式引擎,所以这里我使用的是RegEx特性的C#和PowerShell,假设这些特性是可用的。

正则表达式

代码语言:javascript
复制
[a-z][a-z0-9+.-]*://(?>(?:[a-z0-9!$%&'()*+,.:;=_~-]+@)?(?:[a-z0-9%._~-]+|\[[a-z0-9!$%&'()*+,.:;=_~-]+\]))(?<!\.(?:com|net|org|info|edu|gov|ca)(?::\d+)?)[a-z0-9!#$%&'()*+,./:;=?@_~-]*

细目

  • 模式(http/https/ftp等):[a-z][a-z0-9+\-.]*
  • 原子群 start:(?>
  • 用户名/密码:(?:[a-z0-9!$%&'()*+,.:;=_~-]+@)?
  • 主机名:(?:[a-z0-9%._~-]+|\[[a-z0-9!$%&'()*+,.:;=_~-]+\]))
    • IPv4或普通域:[a-z0-9%._~-]+
    • 或IPv6:\[[a-z0-9!$%&'()*+,.:;=_~-]+\]

  • 主机名(负查找):(?<!\.(?:com|net|org|info|edu|gov|ca)(?::\d+)?)
    • 可选允许端口号:(?::\d+)?

  • 原子群端:)
  • 查询字符串和片段:[a-z0-9!#$%&'()*+,./:;=?@_~-]*

原子组防止表达式的“用户名/密码”和“查询字符串和片段”部分匹配为字符串的"Hostname“部分,而无需我们的验证。

在文本URL中使用RegEx进行匹配

如果您使用这个正则表达式来匹配文本文档中的URL,您可能会发现与“引号”URL或标记链接有关的一些问题。

例如。

代码语言:javascript
复制
[an example](http://example.cox/)
'http://www.example.cox/'
http://www.example.cox/index.html, something interesting in a sentence
You can get it here http://www.example.cox/download.html.

此RegEx作为-is将匹配结尾处的其他字符,因为它们是有效的URL字符,即:

代码语言:javascript
复制
http://example.cox/)
http://www.example.cox/'
http://www.example.cox/index.html,
http://www.example.cox/download.html.

为了避免这种情况,您可以在这样的模式中重复上面的RegEx (很明显,您会删除空格/新行):

代码语言:javascript
复制
(?:
(?<=['])
# RegEx here
(?=['])
|
(?<=["])
# RegEx here
(?=["])
|
(?<=\()
# RegEx here
(?=\))
|
# RegEx here
(?<![.,])
)

因此,这里我们说它有一个引号'/"或括号(在URL之前,假设URL的结尾可以被忽略等等。

如果匹配没有一个括号(,引用'‘’等在最后一部分开始(?<![.,])基本上是说不匹配的最后一个句号.或逗号,字符在网址的末尾,即使它们是完全有效的字符。在完全了解的情况下这样做可能会破坏返回的URL。

票数 1
EN

Stack Overflow用户

发布于 2021-11-09 17:27:13

代码语言:javascript
复制
\/\/.*.(com|ca|info|org|info)(\/|$)

这应该能行

代码语言:javascript
复制
.*.(com|ca|info|org|info)

这个部分将查找从//到TLD的最后部分的整个/,即直到下一个/或行的末尾。您可以以类似的方式在(org|info...)中添加更多的TLD。

https://regex101.com/r/LC1FLQ/1

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69901751

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档