正则表达式仅匹配一次:如何提取多边形全部坐标对?
问题原因及解决方案
为什么你的代码只能输出第一个坐标对?
你的问题出在两个核心点上:
- 正则匹配范围错误:你写的正则是用来匹配整个POLYGON字符串的,所以
m.find()只会找到1个匹配项(整个输入内容),while循环自然只执行一次。 - 重复捕获组的局限性:Java的
Matcher对重复的捕获组(比如你正则里的(([0-9]*\.[0-9]+)\s([0-9]*\.[0-9]+),?)+)只会保留最后一次匹配的内容——你看到第一个结果可能是测试时的小偏差,但本质上这种写法根本无法获取所有坐标对。
解决方法一:分两步匹配(更清晰可靠)
先提取POLYGON括号内的所有坐标内容,再逐个匹配每个坐标对,逻辑清晰且容易维护:
public class PolygonMatcher { public static void main(String[] args) { String input = "POLYGON ((12.789754538957263 36.12443963532555,12.778550292768816 36.089875458584984,12.77760353347314 36.12427601168043))"; // 第一步:提取括号内的坐标块 Pattern polygonPattern = Pattern.compile("POLYGON\\s\\(\\((.*?)\\)\\)"); Matcher polygonMatcher = polygonPattern.matcher(input); if (polygonMatcher.find()) { String coordsContent = polygonMatcher.group(1); // 第二步:逐个匹配每个坐标对 Pattern coordPattern = Pattern.compile("([0-9]*\\.[0-9]+)\\s([0-9]*\\.[0-9]+)"); Matcher coordMatcher = coordPattern.matcher(coordsContent); while (coordMatcher.find()) { System.out.println(coordMatcher.group(1) + " - " + coordMatcher.group(2)); } } } }
解决方法二:用零宽断言直接匹配坐标对
如果你想一步到位,可以用正向预查限定坐标对的上下文,让find()直接定位每个坐标对:
public class PolygonMatcher { public static void main(String[] args) { String input = "POLYGON ((12.789754538957263 36.12443963532555,12.778550292768816 36.089875458584984,12.77760353347314 36.12427601168043))"; Matcher m = Pattern.compile("(?<=POLYGON\\s\\(\\(|,)([0-9]*\\.[0-9]+)\\s([0-9]*\\.[0-9]+)(?=,|\\)\\))").matcher(input); while (m.find()) { System.out.println(m.group(1) + " - " + m.group(2)); } } }
运行结果
两种方法都会输出你期望的内容:
12.789754538957263 - 36.12443963532555 12.778550292768816 - 36.089875458584984 12.77760353347314 - 36.12427601168043
内容的提问来源于stack exchange,提问作者user6845507
相关产品推荐
相关产品推荐

