위도 / 경도 좌표를 일치시키기위한 정규식?


149

위도 / 경도 좌표를 일치시키는 정규식을 만들려고합니다. 배정 밀도 숫자를 일치시키기 위해을 사용 (\-?\d+(\.\d+)?)하고 단일 표현식으로 결합하려고했습니다.

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

나는 이것이 더블, 쉼표, 아마도 약간의 스페이스 및 다른 더블과 일치 할 것으로 예상했지만 작동하지 않는 것 같습니다. 특히 하나 이상의 공간이없는 경우에만 작동합니다. 내가 뭘 잘못 했니?

답변:


117

공백은 \ w가 아니라 \ s입니다.

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

이것이 작동하는지 확인하십시오


1
쉼표 대신 점을 사용해야했습니다 : /^(\-?\d+(\.\d+)?) hereAdot. endMod \ s * (\-? \ d + (\. \ d +)?) $ /
kolodi

위도 및 경도에 허용되는 범위 밖의 값을 허용합니다. 예 : 91,181
Arun Karunagath

이것은 투영 된 공간 참조 시스템의 x / y 좌표에도 적용됩니다.
DeEgge

218

이것은 올바른 범위에 속하는 위도 및 경도 값과 엄격하게 일치합니다.

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

대단해. 범위 확인 포함에 대한 명성.
radj

1
첫 번째 일치 예제에 오타가 있다고 생각합니다. RegEx가 3 개의 값과 일치하는지 의심합니다.
Burkhard

결정된. 그것은 두 개의 별개의 예가되어야했다.
Iain Fraser

7
쉼표의 양쪽에 공백을 허용하도록 수정했습니다 : ^ [-+]? ([1-8]? \ d (\. \ d +)? | 90 (\. 0 +)?) \ s *, \ s * [-+]? (180 (\. 0 +)? | ((1 [0-7] \ d) | ([1-9]? \ d)) (\. \ d +)?) $
puddinman13

2
캡처 ?:하지 않은 그룹 구문과 캡처 극성 을 사용하여 캡처 그룹에서 위도를 얻도록 이것을 변경했습니다.(^[-+]?(?:[1-8]?\d(?:\.\d+)?|90(?:\.0+)?)),\s*([-+]?(?:180(?:\.0+)?|(?:(?:1[0-7]\d)|(?:[1-9]?\d))(?:\.\d+)?))$
narthur157

109

다음 중 하나를 사용하고 있습니다 (10 진수 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})?))$

경도 정규식 시각화


다음 은 액세스 용이성을 위해 두 가지를 모두 테스트하는 요지입니다. 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;
        }
    }
}

이것은 정말 좋은 정규식이었습니다! 그러나 조금 줄일 수 있습니까? :) 그것이 가능하지 않다면, 그것은 괜찮지 만 단축 코드는 언제나 환영합니다 :)
Airikr

@ErikEdgren 나는 그것을 단축하는 방법을 찾지 못했습니다 :(
Marco Ferrari

1
알았어. 정규식은 여전히 ​​굉장합니다;)
Airikr

2
nice visual : D이 웹 사이트에 대해 몰랐습니다! 감사합니다 !
Damiii

SO

19

실제로 정규식 위의 Alix Axel은 위도, 경도 범위의 관점에서 잘못되었습니다.

위도 측정 범위는 –90 ° ~ + 90 °입니다. 경도 측정 범위는 –180 ° ~ + 180 °입니다.

따라서 아래에 주어진 정규식이 더 정확하게 검증됩니다.
또한 내 생각에 따라 아무도 위도 / 경도로 소수점을 제한해서는 안됩니다.

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

또는 목표 C의 경우

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

2
그것은 수용 99을위한 Latitude동안 99의 범위를 벗어 -90, +90때문에 무효.
ako

14
^-?[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)

)? # ... 선택적으로

$ # 문자열의 끝


나는 당신이 가장 우아하다고 생각합니다. 첫째, 이스케이프 문자를 편집하고 바꿀 필요없이 즉시 작동했습니다. 둘째, 짧습니다. 셋째, 이해하기 쉽습니다.
Jim Rota

9

이 시도:

^(\()([-+]?)([\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) 

그러나 요점은 주로 표현의 각 부분을 분해하는 것입니다.


7

보다 엄격한 버전은 다음과 같습니다.

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

1
나는 {1,2}가 먼저오고 나서 {1,3}이되어야한다고 믿습니다
randunel

@Arjan : 고정, 나는 항상 두 가지를 혼동합니다. 감사!
Alix Axel

5

파이썬 :

위도: 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')

예제에서 위도는 실패해야합니다.


4

@ macro-ferrari 나는 그것을 단축시키는 방법을 찾았으며, 정규식 엔진에 대한 최근의 모든 대화에 비추어 미리 보지 않고

const LAT_RE = /^[+-]?(([1-8]?[0-9])(\.[0-9]{1,6})?|90(\.0{1,6})?)$/;

여기에 이미지 설명을 입력하십시오

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

여기에 이미지 설명을 입력하십시오


좋은 설명, 어떻게이 흐름 제어를 사용하여 특정 소프트웨어를 어떻게 사용 했습니까? 이 하나의 regexper.com ?
silentsudo 2018 년

3

\ s (공백)를 사용해야하는 \ w (단어 문자)를 사용하고 있다고 생각합니다. 단어 문자는 일반적으로 [A-Za-z0-9_]로 구성되므로 공백을 제외하고 선택적인 빼기 부호 나 숫자에서 더 이상 일치하지 않습니다.


3

이것은 다음과 같은 형식으로 작동합니다. 31 ͦ 37.4 'E

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

1

루비

경도 -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

0

위도 및 경도에 대한 올바른 패턴을 확인하기 위해 목표 C에서 완전하고 간단한 방법은 다음과 같습니다.

 -( BOOL )textIsValidValue:(NSString*) searchedString
{
    NSRange   searchedRange = NSMakeRange(0, [searchedString length]);
    NSError  *error = nil;
    NSString *pattern = @"^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?),\\s*[-+]?(180(\\.0+)?|((1[0-7]\\d)|([1-9]?\\d))(\\.\\d+)?)$";
    NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern: pattern options:0 error:&error];
    NSTextCheckingResult *match = [regex firstMatchInString:searchedString options:0 range: searchedRange];
    return match ? YES : NO;
}

여기서 searchedString 은 사용자가 해당 텍스트 필드에 입력하는 입력입니다.


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.
}

-1

당신은 이것을 시도 할 수 있습니다 :

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

-2

이 시도:

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

-2

이 시도:

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

5
순수한 코드 답변은 거의 좋은 생각이 아닙니다. 답변에 설명 텍스트를 추가하십시오.
timclutton

훌륭하게 작동합니다. 모든 텍스트에서 정확하게 유효성을 검사하고 위도를 선택합니다. 그러나 소수점 이후에 허용되는 유효 자릿수를 제한하지는 않습니다.
user4325241
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.