GPS经纬度校验异常求助:正则校验有效坐标返回false
嘿,我来帮你搞定这个坐标校验的问题!
首先说下你原来的正则为啥会把有效的坐标判为无效——你的示例纬度53.0102721有7位小数,但原正则里限制了小数部分最多6位(\d{1,6}),所以直接被排除了。另外原正则的写法也有点冗余,比如重复的((\.)|\.\d{1,6})?可以简化。
下面给你两种解决方案,都能确保只接受点.作为小数分隔符,不管系统区域设置如何:
方案一:改进后的正则校验
如果还是想用正则,我调整了规则,去掉了小数位数的限制(你要是需要固定位数可以自己改),同时覆盖了所有合法的纬度/经度范围:
纬度校验(范围:-90 到 90)
public static bool IsValidLatitude(string latitude) { // 匹配正负号可选,要么是90(可带任意个0的小数),要么是0-89的数(可带任意小数) var reg = new Regex(@"^[+-]?(?:90(?:\.0+)?|[1-8]?\d(?:\.\d+)?)$"); return reg.IsMatch(latitude); }
经度校验(范围:-180 到 180)
public static bool IsValidLongitude(string longitude) { // 匹配正负号可选,要么是180(可带任意个0的小数),要么是0-179的数(可带任意小数) var reg = new Regex(@"^[+-]?(?:180(?:\.0+)?|1[0-7]\d(?:\.\d+)?|[1-9]?\d(?:\.\d+)?)$"); return reg.IsMatch(longitude); }
这个正则会接受像53.0102721、-90.0000000、180这类合法坐标,而且只认点作为小数分隔符,逗号的话会直接匹配失败。
方案二:数值转换校验(更推荐)
其实正则很容易踩边界坑,比如后续如果需要支持更多小数位数或者特殊格式,维护起来麻烦。用数值转换的方式更可靠,而且能确保只按点来解析:
using System.Globalization; public static bool IsValidLatitude(string latitude) { if (string.IsNullOrWhiteSpace(latitude)) return false; // 使用InvariantCulture强制以点作为小数分隔符解析,不受系统区域设置影响 if (double.TryParse(latitude, NumberStyles.Float, CultureInfo.InvariantCulture, out double latValue)) { // 检查纬度范围是否在[-90, 90]之间 return latValue >= -90 && latValue <= 90; } return false; } public static bool IsValidLongitude(string longitude) { if (string.IsNullOrWhiteSpace(longitude)) return false; if (double.TryParse(longitude, NumberStyles.Float, CultureInfo.InvariantCulture, out double lonValue)) { // 检查经度范围是否在[-180, 180]之间 return lonValue >= -180 && lonValue <= 180; } return false; }
这个方案的优势:
- 自动处理合法的数值格式(比如
+53.0102721、90、-180.0都能识别) - 用
CultureInfo.InvariantCulture确保不管系统是用逗号还是点作为默认分隔符,都只认点,符合你的要求 - 范围判断更准确,不会出现正则漏判或误判的情况
总结
如果你只需要简单的格式校验,改进后的正则足够用;但如果要确保绝对准确,推荐用数值转换的方案,毕竟坐标本质是数值,用数值类型判断范围最靠谱。
内容的提问来源于stack exchange,提问作者Arie




