使用逻辑OR时在Java正则表达式中正确使用匹配器组
我必须解析一个包含纬度和经度值的字符串。字符串可以采用以下两种格式之一:使用逻辑OR时在Java正则表达式中正确使用匹配器组,java,regex,Java,Regex,我必须解析一个包含纬度和经度值的字符串。字符串可以采用以下两种格式之一: Lat: 33.1234 Lon: -110.1234 Lat, Lon: 33.1234 -110.1234 我正在Java中使用模式匹配器。以下正则表达式正确匹配任一字符串: Lat, Long:\s*([-\d\.]+)[\,\s]+([-\d\.]+)|Lat:\s*([-\d\.]+)\s*Lon[g]?:\s*([-\d\.]+) 然而,配对者有4组。前两个组或后两个组具有lat/lon值,而其他两个组为空
Lat: 33.1234 Lon: -110.1234
Lat, Lon: 33.1234 -110.1234
我正在Java中使用模式匹配器。以下正则表达式正确匹配任一字符串:
Lat, Long:\s*([-\d\.]+)[\,\s]+([-\d\.]+)|Lat:\s*([-\d\.]+)\s*Lon[g]?:\s*([-\d\.]+)
然而,配对者有4组。前两个组或后两个组具有lat/lon值,而其他两个组为空
我意识到我可以测试空值。。。但是我很好奇是否有一种方法可以让matcher只返回两个包含lat&lon值的组,而不管给定的字符串格式是什么?您可以测试输入是否有效,然后分别解析输入。它稍微慢一点(两个正则表达式),但这意味着您将有两个可预测的捕获组 因此,您可以这样做:(显然,可以随意重复使用这些模式:):
此正则表达式与您的两个示例案例相匹配
Lat(?:,\s+Long?:\s*([-\d\.]+)(?:\s+\s*,\s*)(?:Long?:\s+)([-\d\.]+)
我可以想到几个选择(我做了与Matthew相同的假设,假设你的第二次输入是错误的)
使正则表达式更加宽松,并使用命名组。我认为以下内容应该适用于这一点(尽管我不能说我觉得这太易读):
不幸的是,除了至少有两个可分析的双精度(应该添加)之外,这并不能验证输入是否符合预期。但是(至少对我来说)一眼就能看得懂得多。对于正则表达式,
|
字符称为交替运算符。也许这会对谷歌搜索有所帮助。你的第二个例子正确吗?您的正则表达式使我怀疑您的意思是将该值设置为Lat,Long:33.1234,-110.1234
。对此稍作调整以适应“,”Lat/lon值之间的值:Lat(?,\s+Long?):\s*([-\d\.]+\s*,?\s*(?:Long?:\s+([-\d\.]+)@MSquared我更新答案以反映此(?:\s+\s+\s*,\s*)
在这种情况下,需要使用空格或逗号分隔符。因此,第一个[-\d\.]+
不会消耗所有的值字符。如果它都是可选的,\s*,?\s*
将不允许分离,如果没有错误的分隔符,将导致错误匹配。
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
}
}
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
"Lat[:,](?:\\s+Long:)?\\s+(?<lat>[\\-\\+]?\\d+(?:\\.\\d+)?)(?:\\,)?(?:\\sLong?:)?\\s+(?<long>[\\-\\+]?\\d+(?:\\.\\d+)?)"
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();
}