regex - 正则表达式匹配顶级域不是 .com、.net、.org、.info、.edu、.gov 或 .ca 的 url
问题描述
我正在寻找正则表达式来匹配不是来自 .com、.net、.org、.info、.edu、.gov 或 .ca 域的整个 url。TLD 列表可能会随着时间的推移而增长,但这是一个好的开始。
这些将匹配:
这些不匹配:
对于一些背景知识,我希望使用 Exchange Online 的表达式来过滤包含异常/国际链接的入站电子邮件,在我们的例子中,这些链接几乎 100% 是网络钓鱼或垃圾邮件。我们是一家小型企业,只为本地客户提供服务,而且通常所有供应商都是北美人。
解决方案
要匹配整个 URL...
请注意,此实现尝试根据匹配异常 URL 的用法覆盖其他元素:
- 可能的未知安全向量的任何模式(例如
ftp
,ldap
) - 包含基本身份验证用户名和密码
- IPv6 IP 地址
- 指定的端口号(例如
https://www.example.com:8080/
) - 没有路径,即只有主机名/IP 地址
- 请求参数
- 分段
我不知道“Exchange Online”使用的确切正则表达式引擎,所以在这里我使用 C# 和 PowerShell 的 RegEx 功能,假设这些功能可用。
正则表达式
[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+\-.]*
- 原子团开始:
(?>
- 用户名密码:
(?:[a-z0-9!$%&'()*+,.:;=_~-]+@)?
- 主机名:
(?:[a-z0-9%._~-]+|\[[a-z0-9!$%&'()*+,.:;=_~-]+\]))
- IPv4 或普通域:
[a-z0-9%._~-]+
- 或 IPv6:
\[[a-z0-9!$%&'()*+,.:;=_~-]+\]
- IPv4 或普通域:
- 主机名(负面回顾):
(?<!\.(?:com|net|org|info|edu|gov|ca)(?::\d+)?)
- 可选地允许端口号:
(?::\d+)?
- 可选地允许端口号:
- 原子团末端:
)
- 查询字符串和片段:
[a-z0-9!#$%&'()*+,./:;=?@_~-]*
原子组是为了防止表达式的“用户名/密码”和“查询字符串和片段”部分在未经我们验证的情况下匹配为字符串的“主机名”部分。
使用正则表达式匹配文本中的 URL
如果您使用此正则表达式来匹配文本文档中的 URL,您可能会发现“引用”的 URL 或降价链接存在一些问题。
例如
[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 原样将匹配末尾的其他字符,因为它们是有效的 URL 字符,即:
http://example.cox/)
http://www.example.cox/'
http://www.example.cox/index.html,
http://www.example.cox/download.html.
为避免这种情况,您可以以这样的模式重复上面的 RegEx(显然您将删除空格/新行):
(?:
(?<=['])
# RegEx here
(?=['])
|
(?<=["])
# RegEx here
(?=["])
|
(?<=\()
# RegEx here
(?=\))
|
# RegEx here
(?<![.,])
)
所以在这里我们说它在 URL 之前有一个引号'
/"
或括号(
,假设 URL 的结尾可以被忽略等。
如果匹配在开头没有括号(
、引号'
等,最后一部分(?<![.,])
基本上是说不匹配 URL 末尾的最后一个句号.
或逗号,
字符,即使它们是完全有效的字符。在完全了解的情况下执行此操作可能会破坏返回的 URL。
推荐阅读
- excel - 如何创建字典嵌套字典?
- html - 影响下拉宽度的 Optgroup
- reactjs - 使用 react Context (Ionic-React) 时未定义 history.push()
- python - 预测器出错 = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat") RuntimeError:
- python - 变量作为输入 Python 返回 false
- c++ - 不匹配操作符<,即使定义了操作符<
- angular - 了解 Angular 组件的生命周期
- list - Flutter - 类型列表
不是 Widget 类型的子类型 - python - 我如何在python中链接文件?
- terminal - 当光标位于最后一行时,停止 XTerm 在窗口调整大小时向上移动文本?