解析SPARQL结果获取主机名
Parsing SPARQL results to obtain hostname
我有一大堆像这样的三元组:
?s ex:url ?url
其中 ?url
可以是:
www.ex.com/data/1.html
www.ex.com/data/2.html
www.google.com/search
...
是否可以使用 SPARQL 查询以某种方式过滤查询并获得不同的域列表?在示例中,www.ex.com
和 www.google.com
.
像这样的东西:
SELECT distinct ?url
WHERE { ?s ex:url ?url }
但处理每个 url 绑定。当然,我可以得到它们,并在我的程序中一个一个地处理每个 url,但我认为 sparql 查询会更有效地存储内存。我正在使用 Stardog - 如果它有一些自定义功能。
BIND(REPLACE(STR(?url), "^(.*?)/.*", "") AS ?domain)
编辑:正如@JoshuaTailor 在评论中指出的那样,如果 ?url:
中没有方案,STRBEFORE 会更好
BIND(STRBEFORE(?url, "/") AS ?domain)
如果您需要担心 URL 方案(这会丢弃该方案):
BIND(REPLACE(STR(?url), "^(https?://)?(.*?)/.*", "") AS ?domain)
当然,以上仅适用于基本的 http(s) URLs,如果需要处理任意 URLs,则正则表达式会变得更加复杂。
这是一个处理任何或缺失的方案、端口号、身份验证信息和缺失的尾部斜杠的方法:
BIND(REPLACE(?url, "^(?:.*?://)?(?:.*?@)?([^:]+?)(:\d+)?((/.*)|$)", "") AS ?domain)
请注意,使用正则表达式的查询可能会很慢。
您可以使用不需要正则表达式的字符串操作来完成类似的操作。例如,您可以在“//”之后和“/”之前获取 URL 的字符串形式的一部分:
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,在那里你会得到 username: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
The authority component is preceded by a double slash ("//") and is
terminated by the next slash ("/"), question mark ("?"), or number
sign ("#") character, or by the end of the URI.
authority = [ userinfo "@" ] host [ ":" port ]
我不会完成所有这些(也许使用正则表达式来处理复杂的情况会更有意义),但是从 SPARQL 结果中获取 URI 然后使用可能是最简单的一个实际的 URI 解析库来获取主机名。这是最可靠的解决方案,因为 URI 可能非常复杂。
我有一大堆像这样的三元组:
?s ex:url ?url
其中 ?url
可以是:
www.ex.com/data/1.html
www.ex.com/data/2.html
www.google.com/search
...
是否可以使用 SPARQL 查询以某种方式过滤查询并获得不同的域列表?在示例中,www.ex.com
和 www.google.com
.
像这样的东西:
SELECT distinct ?url
WHERE { ?s ex:url ?url }
但处理每个 url 绑定。当然,我可以得到它们,并在我的程序中一个一个地处理每个 url,但我认为 sparql 查询会更有效地存储内存。我正在使用 Stardog - 如果它有一些自定义功能。
BIND(REPLACE(STR(?url), "^(.*?)/.*", "") AS ?domain)
编辑:正如@JoshuaTailor 在评论中指出的那样,如果 ?url:
中没有方案,STRBEFORE 会更好BIND(STRBEFORE(?url, "/") AS ?domain)
如果您需要担心 URL 方案(这会丢弃该方案):
BIND(REPLACE(STR(?url), "^(https?://)?(.*?)/.*", "") AS ?domain)
当然,以上仅适用于基本的 http(s) URLs,如果需要处理任意 URLs,则正则表达式会变得更加复杂。
这是一个处理任何或缺失的方案、端口号、身份验证信息和缺失的尾部斜杠的方法:
BIND(REPLACE(?url, "^(?:.*?://)?(?:.*?@)?([^:]+?)(:\d+)?((/.*)|$)", "") AS ?domain)
请注意,使用正则表达式的查询可能会很慢。
您可以使用不需要正则表达式的字符串操作来完成类似的操作。例如,您可以在“//”之后和“/”之前获取 URL 的字符串形式的一部分:
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,在那里你会得到 username: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
The authority component is preceded by a double slash ("//") and is terminated by the next slash ("/"), question mark ("?"), or number sign ("#") character, or by the end of the URI.
authority = [ userinfo "@" ] host [ ":" port ]
我不会完成所有这些(也许使用正则表达式来处理复杂的情况会更有意义),但是从 SPARQL 结果中获取 URI 然后使用可能是最简单的一个实际的 URI 解析库来获取主机名。这是最可靠的解决方案,因为 URI 可能非常复杂。