正在分析SPARQL结果以获取主机名



我有一个巨大的三元组列表,如下所示:

?s ex:url ?url

其中?url可以是:

www.ex.com/data/1.html
www.ex.com/data/2.html
www.google.com/search
...

使用SPARQL查询,是否可以以某种方式过滤查询并获得不同的域列表?在示例中,www.ex.comwww.google.com

类似这样的东西:

SELECT distinct ?url
WHERE { ?s ex:url ?url }

但是处理每个url绑定。当然,我可以得到所有这些,并在程序中逐一处理每个url,但我认为sparql查询会更节省内存。我正在使用Stardog,以防它有一些自定义功能。

您可以使用不需要正则表达式的字符串操作来完成类似的操作。例如,您可以采用URL的字符串形式的"之后的部分//"并且在"0"之前/":

select ?url ?hostname {
  values ?url { <http://example.org/index.html> }
  bind(strbefore(strafter(str(?url),"//"),"/") as ?hostname)
}
---------------------------------------------------
| url                             | hostname      |
===================================================
| <http://example.org/index.html> | "example.org" |
---------------------------------------------------

这不使用正则表达式,并且可能比使用regex函数的解决方案更快。

然而,这可能会让您获得更多的主机名,例如,如果URL类似于http://username:password@example.org/8080,您可以在其中获得用户名:password@example.org:8080,这不仅仅是主机名。

为了更仔细地做到这一点,您需要选择一个URI/URL等规范,如RFC 3986,并查看语法组件部分。该语法的一些相关产物是:

URI         = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
      hier-part   = "//" authority path-abempty
                  / path-absolute
                  / path-rootless
                  / path-empty

权限组件前面有一个双斜线("//"(以下一个斜线("/"(、问号("?"(或数字结尾符号("#"(字符或通过URI的末尾。

authority   = [ userinfo "@" ] host [ ":" port ]

我不会处理所有这些(也许使用正则表达式来处理复杂的情况会更有意义(,但最简单的方法可能是从SPARQL结果中获取URI,然后使用实际的URI解析库来获取主机名。这是最可靠的解决方案,因为URI可能非常复杂。

使用REPLACE与REGEX:

BIND(REPLACE(STR(?url), "^(.*?)/.*", "$1") AS ?domain)

Yasgui 中的示例

编辑:正如@JoshuaTailor在评论中指出的那样,如果没有方案,STRBEFORE会更好吗?网址:

BIND(STRBEFORE(?url, "/") AS ?domain)

如果你需要担心URL方案(这会放弃该方案(:

BIND(REPLACE(STR(?url), "^(https?://)?(.*?)/.*", "$2") AS ?domain)

当然,以上仅适用于基本的http(s(URL,如果需要处理任意URL,则正则表达式会变得更加复杂。

这里有一个可以处理任何或丢失的方案、端口号、身份验证信息和丢失的尾部斜杠:

BIND(REPLACE(?url, "^(?:.*?://)?(?:.*?@)?([^:]+?)(:\d+)?((/.*)|$)", "$1") AS ?domain)

请注意,使用正则表达式的查询可能非常慢。

相关内容

  • 没有找到相关文章

最新更新