使用正则表达式来处理这种类型的内容总是有点棘手,尤其是当我们没有一个精确的语法可供使用时,但我认为以下方法有效(注意:这仅适用于正值;对于负值,请参阅其他答案以获得能够处理负值的模式):
prefix ogc: <urn:ex:>
select ?lat ?long where {
values ?point { "POINT(48.5 11.7)"^^ogc:wktLiteral }
bind( replace( str(?point), "^[^0-9\\.]*([0-9\\.]+) .*$", "$1" ) as ?long )
bind( replace( str(?point), "^.* ([0-9\\.]+)[^0-9\\.]*$", "$1" ) as ?lat )
}
-------------------
| lat | long |
===================
| "11.7" | "48.5" |
-------------------
关键在于正则表达式。
"^[^0-9\\.]*([0-9\\.]+) .*$" === <non-number>(number) <anything>
"^.* ([0-9\\.]+)[^0-9\\.]*$" === <anything> (number)<non-number>
当然,这只是一个对于
number
的近似值,因为它会匹配带有多个点的内容,但如果数据是好的,你不应该有问题。如果你需要将这些值转换为数值类型,你也可以进行这种类型的转换:
prefix ogc: <urn:ex:>
prefix xsd: <http:
select ?lat ?long where {
values ?point { "POINT(48.5 11.7)"^^ogc:wktLiteral }
bind( xsd:decimal( replace( str(?point), "^[^0-9\\.]*([0-9\\.]+) .*$", "$1" )) as ?long )
bind( xsd:decimal( replace( str(?point), "^.* ([0-9\\.]+)[^0-9\\.]*$", "$1" )) as ?lat )
}
---------------
| lat | long |
===============
| 11.7 | 48.5 | # note: no quotation marks; these are numbers
---------------
请注意,还有其他类型的WKT点,而这段代码无法正确处理它们。例如,维基百科的
Well-known text文章中的一些示例:
POINT ZM (1 1 5 60)
POINT M (1 1 80)
POINT EMPTY
replace
调用。在我看来,现在好多了。 - Joshua Taylor