【问题标题】:Recursive Regex in SPARQL query to identify matching parenthesesSPARQL 查询中的递归正则表达式以识别匹配的括号
【发布时间】: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),它将广泛地提供相同的有效性检查功能。

标签: regex sparql jena


【解决方案1】:

只是为了澄清和补充我对REPLACE 使用的评论,以下应该有效:

SELECT * 
{
    VALUES ?value { 
        "( (1) ((2)) (((3))) 4)" 
        "( (1) ((2)) (((3)) 4)"
        "before (test) after" 
        "before ((test) after"
    }
    bind(!regex(
            replace(?value, '(?=\\()(?:(?=.*?\\((?!.*?\\1)(.*\\)(?!.*\\2).*))(?=.*?\\)(?!.*?\\2)(.*)).)+?.*?(?=\\1)[^(]*(?=\\2$)', '') 
            , '[()]') as ?result)
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多