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

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

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

我期望这个匹配一个双精度数,一个逗号,也许一些空格,和另一个双精度数,但它似乎没有工作。具体来说,它只在没有空间,没有一个或多个的情况下工作。我做错了什么?

173212 次浏览

我相信您在应该使用 s (空格)的地方使用了 w (单词字符)。单词字符通常由[ A-Za-z0-9 _ ]组成,这样就排除了空格,而空格又无法与可选的减号或数字匹配。

空格是 s,不是 w

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

看看能不能成功

这将工作的格式是这样的: 3137.4’E

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

这里有一个更严格的版本:

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

实际上 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+)?)$

试试这个:

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

但重点主要是分解表达式的每一部分。

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

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

火柴

  • + 90.0 -127.554334
  • 45180
  • -90 -180
  • -9万 -18万
  • + 90 + 180
  • 47.1231231,179.9999999

不匹配

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

试试这个:

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

)? # ... 可选

字符串结束

试试这个:

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

露比

经度 -179.999999999. . 180

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

纬度 -89.999999999. . 90

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

巨蟒:

纬度: 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')

在这个例子中纬度应该失败。

我正在使用这些(十进制格式,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


这里的 是一个 gist,为了便于访问,它测试了这两种方法,这里也报告了它们。这是 Java TestNG 测试。你需要 Slf4j,Hamcrest 和龙目岛来运行它:

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

你可以试试这个:

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

我的确找到了一个缩短它的方法,而且根据最近所有关于 regex 引擎的讨论,我没有向前看

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

目标 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;
}

其中 搜索字符串是用户将在相应文本字段中输入的输入。

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

这个在逗号后面加了3个数字以避免错误匹配:

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

正则表达式通过用[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.