Регулярное выражение для сопоставления координат широты / долготы?
Я пытаюсь создать регулярное выражение для сопоставления широты/долготы. Для сопоставления числа двойной точности я использовал (-?d+(.d+)?), и попытался объединить это в одно выражение:
^(-?d+(.d+)?),w*(-?d+(.d+)?)$
Я ожидал, что это будет соответствовать двойной, запятая, возможно, некоторое пространство, и еще один двойной, но это, кажется, не работает. В частности, он работает только в том случае, если нет места, а не одного или нескольких. Что я сделал не так?
16 ответов:
Это будет строго соответствовать значениям широты и долготы, которые попадают в правильный диапазон:
^[-+]?([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})?))$
здесь это суть, которая проверяет оба, сообщается здесь также, для удобства доступа. Это тест 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; } } }
На самом деле Аликс Аксель, выше regex неправильно в широте, долготе диапазоны точки зрения.
диапазон измерений широты от -90° до +90° Диапазон измерения долготы от -180° до + 180°
таким образом, регулярное выражение, приведенное ниже, проверяет более точно.
Кроме того, согласно моей мысли, никто не должен ограничивать десятичную точку в широте/долготе.^([-+]?\d{1,2}([.]\d+)?),\s*([-+]?\d{1,3}([.]\d+)?)$или для цели C
^([-+]?\d{1,2}([.]\d+)?),\s*([-+]?\d{1,3}([.]\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}# с последующим от одного до 10 цифр (т. е. 0-9999999999)
)?# ...необязательно
$# конец строки
попробуйте это:
^(\()([-+]?)([\d]{1,2})(((\.)(\d+)(,)))(\s*)(([-+]?)([\d]{1,3})((\.)(\d+))?(\)))$проверьте это по адресу:
вставьте выражение в верхнем поле, а затем поместите такие вещи в нижнем поле:
(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)но дело в основном просто сломать каждая часть выражения.
вот более строгая версия:
^([-+]?\d{1,2}[.]\d+),\s*([-+]?\d{1,3}[.]\d+)$
- широта =
-90--+90- долгота =
-180--+180
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')широта должна завершиться неудачей в Примере.
Я считаю, что вы используете \w (символ слова), где вы должны использовать \s (пробелы). Символы Word обычно состоят из [A-Za-z0-9_], так что исключает Ваше пространство, которое затем не соответствует необязательному знаку минус или цифре.
Это будет работать для формата, как это: 31 37.4 ' E
^[ -]?\d{1,2} [][ ]\d{1,2}.?\d{1,2} [] \x27[ ] \w$
@macro-ferrari Я нашел способ сократить его, и без оглядки aheads в свете всех последних разговоров о двигатели регулярное выражение
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})?)$/;
Рубин
долгота -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)`




Comments