SPARQL 查询中的递归正则表达式以识别匹配的括号

Recursive Regex in SPARQL query to identify matching parentheses

我正在尝试使用 SPARQL 来查询具有带平衡括号的正则表达式的文字。 所以应该返回“( (1) ((2)) (((3))) 4)”,但是“( ((1) ((2)) (((3)) 4)”,我删除了一个“3”后的右括号不应返回。

我之前曾在这里寻找合适的正则表达式:Regular expression to match balanced parentheses

并且一直在尝试实现rogal111建议的regex,如下:

\(([^()]|(?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 上测试)确实有效,但也 returns 不正确的输出,如查询所示下面:

SELECT ?lf
WHERE
{
  BIND("((test)" AS ?l)
  FILTER REGEX(?l, "\(([^()]|(?R))*\)").
}

我不确定这是故意的、错误还是我做错了什么。最终我想让它在基于 Jena 的 triplestore 上运行。谁能帮我解决这个问题?

只是为了澄清和补充我对 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)
}