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

时间:2010-08-19 03:26:18

标签: regex

我正在尝试创建匹配纬度/经度坐标的正则表达式。为了匹配我使用(\-?\d+(\.\d+)?)的双精度数,并尝试将其组合成单个表达式:

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

我希望这匹配一个双精度数,一个逗号,也许是一些空格,另一个双精度数,但它似乎不起作用。具体来说,它只有在没有空间而不是一个或多个空间时才有效。我做错了什么?

19 个答案:

答案 0 :(得分:173)

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

^[-+]?([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,1799.99999999

不匹配

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

答案 1 :(得分:103)

空白是\ s,而不是\ w

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

看看是否有效

答案 2 :(得分:85)

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

纬度

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

Latitude Regular expression visualization

经度

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

Longitude Regular expression visualization

Here是一个要点,它既可以测试这两个,也可以在这里进行测试,以便于访问。这是一个Java TestNG测试。你需要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;
        }
    }
}

答案 3 :(得分:19)

实际上Alix Axel,上面的正则表达式在纬度,经度范围上是错误的。

纬度测量范围为-90°至+ 90° 经度测量范围为-180°至+ 180°

因此,下面给出的正则表达式可以更准确地验证 另外,根据我的想法,没有人应该限制纬度/经度的小数点。

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

目标C的OR

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

答案 4 :(得分:9)

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

正则表达式细分:

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

-?#接受负值

^#字符串开头

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

(?:#尝试匹配......

\.#小数点

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

)?#...可选

$#字符串结尾

答案 5 :(得分:8)

试试这个:

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

请查看:

http://regexpal.com/

将表达式粘贴在顶部框中,然后将这样的内容放在底部框中:

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

正则表达式细分:

^                    # 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) 

但重点主要在于分解表达的每一部分。

答案 6 :(得分:7)

这是一个更严格的版本:

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

答案 7 :(得分:4)

的Python:

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

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

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

答案 8 :(得分:3)

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

答案 9 :(得分:3)

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

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

答案 10 :(得分:2)

@macro-ferrari我确实找到了缩短它的方法,并且根据最近关于regex engines

的所有谈话,没有展望未来
const LAT_RE = /^[+-]?(([1-8]?[0-9])(\.[0-9]{1,6})?|90(\.0{1,6})?)$/;

enter image description here

const LONG_RE = /^[+-]?((([1-9]?[0-9]|1[0-7][0-9])(\.[0-9]{1,6})?)|180(\.0{1,6})?)$/;

enter image description here

答案 11 :(得分:2)

正则表达式通过将 [0-9] 的多次使用替换为 [0-9] 的子集来缩短 @marco-ferrari 解决方案。还从各个地方删除了不必要的量词,例如 ?:

lat  "^([+-])?(?:90(?:\\.0{1,6})?|((?:|[1-8])[0-9])(?:\\.[0-9]{1,6})?)$";
long "^([+-])?(?:180(?:\\.0{1,6})?|((?:|[1-9]|1[0-7])[0-9])(?:\\.[0-9]{1,6})?)$";


**Matches for Lat**

Valid between -90 to +90 with up to 6 decimals.

**Matches for Long**

Valid between -180 to +180 with up to 6 decimals.

答案 12 :(得分:0)

<强>红宝石

经度 -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

答案 13 :(得分:0)

你可以试试这个:

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})?$/;

答案 14 :(得分:0)

PHP

这是PHP的版本(输入值为$latitude$longitude):

$latitude_pattern  = '/\A[+-]?(?:90(?:\.0{1,18})?|\d(?(?<=9)|\d?)\.\d{1,18})\z/x';
$longitude_pattern = '/\A[+-]?(?:180(?:\.0{1,18})?|(?:1[0-7]\d|\d{1,2})\.\d{1,18})\z/x';
if (preg_match($latitude_pattern, $latitude) && preg_match($longitude_pattern, $longitude)) {
  // Valid coordinates.
}

答案 15 :(得分:0)

这个在逗号后强制使用 3 个数字以避免错误匹配:

(?<latitude>-?\d+\.\d{3,10}),(?<longitude>-?\d+\.\d{3,10})

答案 16 :(得分:-1)

试试这个:

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

答案 17 :(得分:-1)

试试这个:

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

答案 18 :(得分:-2)

/(-?\d{1,2}[.]\d+)(?U:.*)(-?1?[0-8]?\d[.]\d+)/