SPARQL精确匹配正则表达式

5
我正在使用以下SPARQL查询语句从DBPedia中提取与特定信息框匹配的页面:
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX dbpedia: <http://dbpedia.org/property/>
PREFIX res:<http://dbpedia.org/resource/>
SELECT DISTINCT *
WHERE {
?page dbpedia:wikiPageUsesTemplate ?template .
?page rdfs:label ?label .
FILTER (regex(?template, 'Infobox_artist')) .
FILTER (lang(?label) = 'en')
}
LIMIT 100

在查询语句的这一行中:
FILTER (regex(?template, 'Infobox_artist')) .

我获取了所有以“artist”开头的信息框,如“artist_discography”和其他我不需要的信息框。我的问题是:如何仅使用正则表达式获取与“infobox_artist”完全匹配的信息框?

3个回答

7

作为正则表达式,您应该能够按照以下方式限制搜索:

FILTER (regex(?template, '^Infobox_artist$')) .
  • ^ 表示字符串的开头
  • $ 表示字符串的结尾

在正则表达式中。

NB:我没有使用SPARQL,所以这可能不起作用。


这会给SPARQL端点带来(在我看来)不必要的负担。下面建议另一种方法。 - Jeen Broekstra

3

@beny23提出的方法虽然可行,但效率非常低下。使用正则表达式基本上是为了匹配一个确切的值,这可能会给被查询的端点带来不必要的负担。这是一种不好的做法。

?template的值是一个URI,因此您应该使用值比较(甚至可以像@cygri演示的那样内联):

SELECT DISTINCT * {
    ?page dbpedia:wikiPageUsesTemplate ?template .
    ?page rdfs:label ?label .
    FILTER (lang(?label) = 'en')
    FILTER (?template = <http://dbpedia.org/resource/Template:Infobox_artist> )
}
LIMIT 100

你仍然可以在代码中轻松地调整此查询字符串以适应不同类型的信息框。此外:根据您用于创建和执行SPARQL查询的工具包,您可能有一些编程替代方案,使查询重用变得更加容易。
例如,你可以创建一个“准备好的查询”,并在执行之前将绑定设置为特定的值以便重复使用。例如,在Sesame中,你可以这样做:
String q = "SELECT DISTINCT * { " +
               " ?page dbpedia:wikiPageUsesTemplate ?template . " +
               " ?page rdfs:label ?label . " +
               " FILTER (lang(?label) = 'en') " +
               " } LIMIT 100 ";

TupleQuery query = conn.prepareTupleQuery(SPARQL, q);
URI infoboxArtist = f.createURI(DBPedia.NAMESPACE, "Template:Infobox_artist");
query.setBinding("template", infoboxArtist); 

TupleQueryResult result = query.evaluate();
< p >(顺便说一下:在此使用Sesame进行示例,因为我在Sesame开发团队上,但毫无疑问其他SPARQL / RDF工具包具有类似功能)< / p > 作为旁注:由于我是Sesame开发团队的成员,所以展示使用Sesame的示例,但毫无疑问其他SPARQL/RDF工具包具有相似的功能。

1
如果您只想进行直接字符串比较,那么您不需要正则表达式!这样更简单和更快:
SELECT DISTINCT * {
    ?page dbpedia:wikiPageUsesTemplate
        <http://dbpedia.org/resource/Template:Infobox_artist> .
    ?page rdfs:label ?label .
    FILTER (lang(?label) = 'en')
}
LIMIT 100

我一开始使用了这个查询,但由于我有许多信息框需要查询,所以我使用了正则表达式,这样我就可以更改信息框的名称。谢谢! - Funmatica
@Funmatica,这个想法不好。很抱歉,但它确实不好。即使您想要能够重复使用查询以获取不同的信息框,也不应该使用正则表达式。相反,请使用完整的信息框模板URI:FILTER(?template = <http://dbpedia.org/resource/Template:Infobox_artist>)。更高效,对您正在查询的端点负担更小,通常是更好的做法。 - Jeen Broekstra

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接