用于匹配纬度/经度坐标的正则expression式?

我正在创build一个匹配纬度/经度坐标的正则expression式。 为了匹配我使用过的双精度数字(\-?\d+(\.\d+)?) ,并试图将其结合到一个expression式中:

 ^(\-?\d+(\.\d+)?),\w*(\-?\d+(\.\d+)?)$ 

我希望这匹配一个双,一个逗号,也许一些空间,另一个双,但它似乎并没有工作。 具体来说,只有在没有空间的情况下才有效,而不是一个或多个。 我做错了什么?

空白是\ s,而不是\ w

 ^(\-?\d+(\.\d+)?),\s*(\-?\d+(\.\d+)?)$ 

看看这是否有效

这一个将严格地匹配在正确的范围内的纬度和经度值:

 ^[-+]?([1-8]?\d(\.\d+)?|90(\.0+)?),\s*[-+]?(180(\.0+)?|((1[0-7]\d)|([1-9]?\d))(\.\d+)?)$ 

火柴

  • +90.0,-127.554334
  • 45,180
  • -90,-180
  • -90.000,-180.0000
  • +90,+180
  • 47.1231231,179.99999999

不匹配

  • -90。,-180。
  • +90.1,-100.111
  • -91,123.456
  • 045,180

我正在使用这些(十进制格式,6位十进制数字):

纬度

 ^(\+|-)?(?:90(?:(?:\.0{1,6})?)|(?:[0-9]|[1-8][0-9])(?:(?:\.[0-9]{1,6})?))$ 

纬度正则表达式可视化

经度

 ^(\+|-)?(?:180(?:(?:\.0{1,6})?)|(?:[0-9]|[1-9][0-9]|1[0-7][0-9])(?:(?:\.[0-9]{1,6})?))$ 

经度正则表达式可视化


这里有一个testing的两个要点,这里也报道,为便于访问。 这是一个Java TestNGtesting。 你需要Slf4j,Hamcrest和Lombok来运行它:

 import static org.hamcrest.Matchers.*; import static org.hamcrest.MatcherAssert.*; import java.math.RoundingMode; import java.text.DecimalFormat; import lombok.extern.slf4j.Slf4j; import org.testng.annotations.Test; @Slf4j public class LatLongValidationTest { protected static final String LATITUDE_PATTERN="^(\\+|-)?(?:90(?:(?:\\.0{1,6})?)|(?:[0-9]|[1-8][0-9])(?:(?:\\.[0-9]{1,6})?))$"; protected static final String LONGITUDE_PATTERN="^(\\+|-)?(?:180(?:(?:\\.0{1,6})?)|(?:[0-9]|[1-9][0-9]|1[0-7][0-9])(?:(?:\\.[0-9]{1,6})?))$"; @Test public void latitudeTest(){ DecimalFormat df = new DecimalFormat("#.######"); df.setRoundingMode(RoundingMode.UP); double step = 0.01; Double latitudeToTest = -90.0; while(latitudeToTest <= 90.0){ boolean result = df.format(latitudeToTest).matches(LATITUDE_PATTERN); log.info("Latitude: tested {}. Result (matches regex): {}", df.format(latitudeToTest), result); assertThat(result, is(true)); latitudeToTest += step; } latitudeToTest = -90.1; while(latitudeToTest >= -200.0){ boolean result = df.format(latitudeToTest).matches(LATITUDE_PATTERN); log.info("Latitude: tested {}. Result (matches regex): {}", df.format(latitudeToTest), result); assertThat(result, is(false)); latitudeToTest -= step; } latitudeToTest = 90.01; while(latitudeToTest <= 200.0){ boolean result = df.format(latitudeToTest).matches(LATITUDE_PATTERN); log.info("Latitude: tested {}. Result (matches regex): {}", df.format(latitudeToTest), result); assertThat(result, is(false)); latitudeToTest += step; } } @Test public void longitudeTest(){ DecimalFormat df = new DecimalFormat("#.######"); df.setRoundingMode(RoundingMode.UP); double step = 0.01; Double longitudeToTest = -180.0; while(longitudeToTest <= 180.0){ boolean result = df.format(longitudeToTest).matches(LONGITUDE_PATTERN); log.info("Longitude: tested {}. Result (matches regex): {}", df.format(longitudeToTest), result); assertThat(result, is(true)); longitudeToTest += step; } longitudeToTest = -180.01; while(longitudeToTest >= -300.0){ boolean result = df.format(longitudeToTest).matches(LONGITUDE_PATTERN); log.info("Longitude: tested {}. Result (matches regex): {}", df.format(longitudeToTest), result); assertThat(result, is(false)); longitudeToTest -= step; } longitudeToTest = 180.01; while(longitudeToTest <= 300.0){ boolean result = df.format(longitudeToTest).matches(LONGITUDE_PATTERN); log.info("Longitude: tested {}. Result (matches regex): {}", df.format(longitudeToTest), result); assertThat(result, is(false)); longitudeToTest += step; } } } 

其实阿尔克斯Axel,在正则expression式上在纬度,经度范围上是错误的。

纬度测量范围从-90°到+ 90°经度测量范围从-180°到+ 180°

所以下面给出的正则expression式更准确地validation。
另外,按照我的想法,没有人应该限制经纬度的小数点。

 ^([-+]?\d{1,2}([.]\d+)?),\s*([-+]?\d{1,3}([.]\d+)?)$ 

或目标C

 ^([-+]?\\d{1,2}([.]\\d+)?),\\s*([-+]?\\d{1,3}([.]\\d+)?)$ 

这是一个更严格的版本:

 ^([-+]?\d{1,2}[.]\d+),\s*([-+]?\d{1,3}[.]\d+)$ 
  • 纬度= -90+90
  • 经度= -180+180

尝试这个:

 ^(\()([-+]?)([\d]{1,2})(((\.)(\d+)(,)))(\s*)(([-+]?)([\d]{1,3})((\.)(\d+))?(\)))$ 

检查出来在:

http://regexpal.com/

将expression式粘贴到顶部框中,然后在底部框中放置这样的东西:

 (80.0123, -34.034) (80.0123) (80.a) (980.13, 40) (99.000, 122.000) 

正则expression式细分:

 ^ # The string must start this way (there can't be anything before). (\() # An opening parentheses (escaped with a backslash). ([-+]?) # An optional minus, or an optional plus. ([\d]{1,2}) # 1 or 2 digits (0-9). ( # Start of a sub-pattern. ( # Start of a sub-pattern. (\.) # A dot (escaped with a backslash). (\d+) # One or more digits (0-9). (,) # A comma. ) # End of a sub-pattern. ) # End of a sub-pattern. (\s*) # Zero or more spaces. ( # Start of a sub-pattern. ([-+]?) # An optional minus, or an optional plus. ([\d]{1,3}) # 1 to 3 digits (0-9). ( # Start of a pattern. (\.) # A dot (escaped with a backslash). (\d+) # One or more digits (0-9). )? # End of an optional pattern. (\)) # A closing parenthesis (escaped with a backkslash). ) # End of a pattern $ # The string must end this way (there can't be anything after). 

现在,这不是做的只限于这个范围:

 (-90 to +90, and -180 to +180) 

相反,它简单地限制到这个范围:

 (-99 to +99, -199 to +199) 

但重点只是要分解每一个expression方式。

 ^-?[0-9]{1,3}(?:\.[0-9]{1,10})?$ 

正则expression式细分:

 ^-?[0-9]{1,3}(?:\.[0-9]{1,10})?$ 

-? #接受负值

^ #string的开头

[0-9]{1,3} #匹配1-3位(即0-999)

(?: #尝试匹配…

\. #小数点

[0-9]{1,10} #后跟1到10位数字(即0-9999999999)

)? #…可选

$ #string结尾

python:

Latitude: result = re.match("^[+-]?((90\.?0*$)|(([0-8]?[0-9])\.?[0-9]*$))", '-90.00001')

Longitude: result = re.match("^[+-]?((180\.?0*$)|(((1[0-7][0-9])|([0-9]{0,2}))\.?[0-9]*$))", '-0.0000')

在示例中,纬度应该失败。

我相信你正在使用\ w(单词字符),你应该使用\ s(空格)。 单词字符通常由[A-Za-z0-9_]组成,因此会排除您的空间,从而无法在可选的减号或数字上匹配。

这将适用于这样的格式:31ͦ37.4'E

^ [ – ]?\ d {1,2} [] ͦ[] \ d {1,2}。?\ d {1,2} [] \ x27 [] \ w $

ruby

经度-179.99999999..180

 /^(-?(?:1[0-7]|[1-9])?\d(?:\.\d{1,8})?|180(?:\.0{1,8})?)$/ === longitude.to_s 

纬度-89.99999999..90

 /^(-?[1-8]?\d(?:\.\d{1,8})?|90(?:\.0{1,8})?)$/ === latitude.to_s 

你可以试试这个:

 var latExp = /^(?=.)-?((8[0-5]?)|([0-7]?[0-9]))?(?:\.[0-9]{1,20})?$/; var lngExp = /^(?=.)-?((0?[8-9][0-9])|180|([0-1]?[0-7]?[0-9]))?(?:\.[0-9]{1,20})?$/; 

尝试这个:

 ^[-+]?(([0-8]\\d|\\d)(\\.\\d+)?|90(\\.0+)?)$,\s*^[-+]?((1[0-7]\\d(\\.\\d+)?)|(180(\\.0+)?)|(\\d\\d(\\.\\d+)?)|(\\d(\\.\\d+)?))$ 

尝试这个:

 (?<!\d)([-+]?(?:[1-8]?\d(?:\.\d+)?|90(?:\.0+)?)),\s*([-+]?(?:180(?:\.0+)?|(?:(?:1[0-7]\d)|(?:[1-9]?\d))(?:\.\d+)?))(?!\d)` 
 /(-?\d{1,2}[.]\d+)(?U:.*)(-?1?[0-8]?\d[.]\d+)/