使用 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.html
→ example.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 来详细说明:
此正则表达式从 url 中提取带有 TLD 的域:
TRIM(REGEXP_EXTRACT(REGEXP_REPLACE(REGEXP_REPLACE(Address, "https?://", ""), R"^(w{3}\.)?", ""), "([^/?]+)"))
此表达式从 http://www.example.com/page.html
→ example.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 来详细说明: