我必须解析一个包含纬度和数字的字符串。经度值。字符串可以采用以下两种格式之一:
Lat: 33.1234 Lon: -110.1234
Lat, Lon: 33.1234 -110.1234
我正在使用Pattern& Java中的匹配器。以下正则表达式正确匹配字符串:
Lat, Long:\s*([-\d\.]+)[\,\s]+([-\d\.]+)|Lat:\s*([-\d\.]+)\s*Lon[g]?:\s*([-\d\.]+)
然而......匹配者有4组。前两组或后两组具有lat / lon值,另外两组为null。
我意识到我可以测试null ...但我很好奇是否有一种方法只让匹配器返回两个包含lat&组的组。 lon值是否与给出的字符串格式无关?
答案 0 :(得分:2)
此正则表达式匹配您的两个示例案例。
Lat(?:,\s+Long?)?:\s*([-\d\.]+)(?:\s+|\s*,\s*)(?:Long?:\s+)?([-\d\.]+)
https://regex101.com/r/D3aBpX/1
Lat # Lat label
(?: , \s+ Long? )? # optional , Long label
: # colon
\s* # optional space
( [-\d\.]+ ) # (1), lat value
(?: \s+ | \s* , \s* ) # Seperated by space or comma ( must have one )
(?: Long?: \s+ )? # optional Long label and colon
( [-\d\.]+ ) # (2), long value
答案 1 :(得分:0)
您可以测试输入是否有效,然后单独解析输入。它有点慢(两个正则表达式),但这意味着你将拥有两个可预测的捕获组。
所以你可以这样做:(显然,可以随意重复使用模式:)):
if (Pattern.compile("Lat[,:].*Long?:.*").matcher(inputString).matches()) {
Matcher m = Pattern.compile(".*([-\d\.]+)\b.*([-\d\.]+).*")
.matcher(inputString);
if (m.matches()) {
// m.group(1) is always lat, and m.group(2) is always lon
}
}
答案 2 :(得分:0)
我能想到的一些选择(我做了同样的假设,马修对你的第二次输入做错了。)
使正则表达式更宽松并使用命名组。我认为以下内容适用于此(虽然我不能说我觉得这太可读了):
"Lat[:,](?:\\s+Long:)?\\s+(?<lat>[\\-\\+]?\\d+(?:\\.\\d+)?)(?:\\,)?(?:\\sLong?:)?\\s+(?<long>[\\-\\+]?\\d+(?:\\.\\d+)?)"
使用Scanner
检查值而不是正则表达式。有点像:
final double latitude, longitude;
try (final Scanner scanner = new Scanner(input)) {
while (!scanner.hasNextDouble()) scanner.next();
latitude = scanner.nextDouble();
while (!scanner.hasNextDouble()) scanner.next();
longitude = scanner.nextDouble();
}
不幸的是,除了在其中至少有两个可解析的双精度(应该添加)之外,这并不能确认输入符合预期。然而,(至少对我来说)一目了然更具可读性。