【发布时间】:2020-06-23 12:16:33
【问题描述】:
我正在尝试使用 SPARQL 来查询具有带平衡括号的正则表达式的文字。 所以应该返回“((1)((2))(((3)))4)”,但是“((1)((2))(((3))4)”,我删除了一个“3”后的右括号,不应返回。
我以前在这里寻找合适的正则表达式:Regular expression to match balanced parentheses
并且一直在尝试实现rogal111建议的正则表达式,如下:
\(([^()]|(?R))*\)
这个正则表达式遵循 PCRE 语法,我理解是 W3C 标准,应该遵循 SPARQL。 根据链接示例http://regex101.com/r/lF0fI1/1,这应该适用于上述示例。
我已经在一个基于 Jena 的三重商店和一个基于 Virtuoso 的三重商店上测试了这一点。
Jena:当我尝试使用下面的查询为 SPARQL 实现它时,它说 (?R) 内联修饰符是未知的。
SELECT ?lf
WHERE
{
BIND("(test)" AS ?l)
FILTER REGEX(?l, "\\(([^()]|(?R))*\\)").
}
返回的完整错误信息如下。
Regex pattern exception: java.util.regex.PatternSyntaxException: Unknown inline modifier near index 11 \(([^()]|(?R))*\)
Virtuoso:基于 Virtuoso 的三元存储(测试于:https://sparql.uniprot.org/sparql)确实有效,但也返回了不正确的输出,如下面的查询所示:
SELECT ?lf
WHERE
{
BIND("((test)" AS ?l)
FILTER REGEX(?l, "\\(([^()]|(?R))*\\)").
}
我不确定这是故意的、错误的还是我做错了什么。最终,我想让它在基于 Jena 的 Triplestore 上工作。谁能帮我解决这个问题?
【问题讨论】:
-
大部分 RDF 工具(包括 Jena)都是用 Java 编写的,但 Java regex libraray 不支持 regex 递归。查看stackoverflow.com/questions/47162098,其中讨论了非递归解决方案并将其应用于您的案例。还建议使用
REPLACE而不是REGEX并应用过滤器检查替换结果是否为空,这表明整个文字匹配 -
Java 正则表达式不支持递归。
-
感谢两位的回复!因此,如果我正确理解您的答案,基于 Java 的三重存储无法完全实现 w3.org/TR/sparql11-query 建议?那我看看另一种解决方案。
-
@Wytz SPARQL 语法 REGEXP 在w3.org/TR/sparql11-query/#func-regex 指向 XPath 和 XQuery 部分在 w3.org/TR/xpath-functions/#regex-syntax 这反过来又导致 w3.org/TR/xmlschema-2/#regexs 并且在这些文档中我找不到需要支持的参考递归...
-
@DamyanOgnyanov 你是对的,看来我误解了w3.org/TR/xpath-functions/#regex-syntax 上的描述。我认为这意味着即使语法有时可能与例如不同。 Perl(他们指的是,我相信应该是 PCRE),它将广泛地提供相同的有效性检查功能。