使用 RE2 / regex 提取没有子域的域而不是 www?

Extracting domain without subdomains other then www with RE2 / regex?

此正则表达式从 url 中提取带有 TLD 的域:

TRIM(REGEXP_EXTRACT(REGEXP_REPLACE(REGEXP_REPLACE(Address, "https?://", ""), R"^(w{3}\.)?", ""), "([^/?]+)"))

此表达式从 http://www.example.com/page.htmlexample.com,这是预期的输出。

但是 它仅在子域为 www 的情况下有效。在其他情况下它不处理。

如果我改用 TRIM(REGEXP_EXTRACT(REGEXP_REPLACE(REGEXP_REPLACE(Address, "https?://", ""), R"^([a-zA-Z0-9]{1,}\.)?", ""), "([^/?]+)")) - 整个域名消失,只剩下 TLD。

有什么方法可以处理任何子域,哪个字符串可以用[a-zA-Z0-9]{1,}表示?

预期输出为

+-------------------+-------------+
| sites.example.com | example.com |
+-------------------+-------------+
| m.example.com     | example.com |
+-------------------+-------------+
| ww2.example.com   | example.com |
+-------------------+-------------+
| mail.example.com  | example.com |
+-------------------+-------------+
| blog.example.com  | example.com |
+-------------------+-------------+
| shop.example.com  | example.com |
+-------------------+-------------+
| cdn.example.com   | example.com |
+-------------------+-------------+
| api.example.com   | example.com |
+-------------------+-------------+
| 1.example.com     | example.com |
+-------------------+-------------+

保留摆脱协议和路径的代码,只留下域我建议使用捕获子域、域和 TLD 的正则表达式。然后我们可以用域和 TLD 替换匹配项。

请注意 URL 可能包含 ftp 协议或带有用户和可选密码的身份验证部分,或者协议也可能被省略。所以这当然取决于你的数据。

示例:

ftp://something.example.com/folder
http://user:pswd@subdomain.example.com/path
//xyz-123.sub-domain.example.com

我玩过 Regex101:https://regex101.com/r/X4UoCx/1/

正则表达式为:

^((?:\w[\w-]{0,61}\.)*)(\w[\w-]{0,61}\.[a-z]{2,62})$

解释:

  • ()用于抓取零件。在这里,我们在捕获 n°1 中捕获子域,在捕获 n°2 中捕获具有 TLD 的域。
  • (?:) 是非捕获组。这里它用于子域模式,因为它始终是一个带有最终连字符的单词,后跟一个点、零个或多个点。所以\w[\w-]{0,61}\.表示一个单词字符(a-z + A-Z + 0-9)然后是一个单词字符或连字符,0最多61次。这是因为最大长度似乎是 62 个字符。然后是一个点。
  • 我们想重复这个模式,因为我们可以有多个子域。这就是为什么将此表达式放在非捕获组中的原因,该组可以是 0 次或 n 次:(?:\w[\w-]{0,61}\.)*
  • 我们将捕获此子域以供以后使用括号:((?:\w[\w-]{0,61}\.)*)
  • 现在,第二个有趣的组是我们的域和 TLD:(\w[\w-]{0,61}\.[a-z]{2,62})
    • 域是 \w[\w-]{0,61},因为它不能以连字符开头。
    • 顶级域名是\.[a-z]{2,62}

所以最后,您只需将匹配的完整域替换为匹配的组号 2,其中包含您的域和 TLD。 我不知道 RE2 正则表达式替换方法的确切语法,因此替换字符串可能是 """".

字段是 Address,下面的技巧:

REGEXP_EXTRACT(
 REGEXP_EXTRACT(
  REGEXP_REPLACE(Address, "^(.*//)", ""),
 "^([^/]*)"),
R"([^\.]*\.[^\.]*)$")

第 3 行到第 5 行的快速细分使用 Calculated Field 的非嵌套解释:

  • 第 3 行 REGEXP_REPLACE(Address, "^(.*//)", ""):删除 http//https// 部分
  • 第 4 行:REGEXP_EXTRACT(Line 3, "^([^/]*)"):提取所有字符直到第一个 /
  • 第 5 行:REGEXP_EXTRACT(Line 4, R"([^\.]*\.[^\.]*)$"):提取字符串末尾的所有字符,直到第二个 .

Editable Google Data Studio Report (Embedded Google Sheets 数据源)和一张 GIF 来详细说明: