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)
}
我正在尝试使用 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)
}