php以十进制格式验证纬度/经度字符串

时间:2011-09-26 00:47:04

标签: php regex

好吧,我有一个我称之为经度和纬度坐标的大量列表。那说我也有一些来源,我从这里拉出这些坐标。其中一些来自get / post方法,这可能会导致我的网站/服务中出现潜在的安全漏洞。所以我想弄清楚如何通过PHP验证经度和纬度。我正在通过preg_match思考一些正则表达式。但我可能是错的,也许有人想提出一个更简单的方法。我已经尝试了自己的概念,并尝试了各种互联网酿造概念,试图找到一个正则表达式模式,通过preg_match为我验证这些(或者如果你有更好的建议,我会全神贯注地再次类似)。

我最后一次失败的尝试才最终进入并来到这里......

preg_match('^(\-?\d+(\.\d+)?),\s*(\-?\d+(\.\d+)?)$', $geoResults['latitude']))

产生“preg_match()[function.preg-match]:找不到结束分隔符'^'”作为我的错误。我试过的最后几次尝试产生了这个错误,所以我不知道它是什么或意味着什么。

8 个答案:

答案 0 :(得分:24)

这是一个有点老问题,但无论如何我在这里发布我的解决方案:

preg_match('/^[-]?(([0-8]?[0-9])\.(\d+))|(90(\.0+)?);[-]?((((1[0-7][0-9])|([0-9]?[0-9]))\.(\d+))|180(\.0+)?)$/', $geoResults['latlng']);

我在这里假设你拆分了lat。来自lng。用分号。如果你想只检查lat。或者只是lng。这里是regexp的;

Rgx for lat。:

/^[-]?(([0-8]?[0-9])\.(\d+))|(90(\.0+)?)$/

Lgx for lng。:

/^[-]?((((1[0-7][0-9])|([0-9]?[0-9]))\.(\d+))|180(\.0+)?)$/

这是一个改进的在线演示: https://regex101.com/r/bV5fA1/1

答案 1 :(得分:23)

在匹配序列的开头和结尾添加正斜杠,使其成为有效的正则表达式语法:

preg_match('/^(\-?\d+(\.\d+)?),\s*(\-?\d+(\.\d+)?)$/', $geoResults['latitude']);

关于是否使用正则表达式(正则表达式)的问题,在这种情况下使用正则表达式(PCRE preg_match())是保护您网站的最佳方式。当匹配变量复杂的字符串排列时,正则表达式是要走的路。开发人员通常会使用正则表达式来匹配静态字符串,例如'abc'。这是strpos()str_replace()更好的选择。

答案 2 :(得分:1)

为什么不使用现代和单元测试的Assertion库?

示例Value Object类:

<?php
namespace MyApp\ValueObject;

use Assert\Assertion;

class Location
{
    private $lat;
    private $lon;

    public function __construct($lat, $lon)
    {
        Assertion::greaterOrEqualThan($lat, -90.0);
        Assertion::lessOrEqualThan($lat, 90.0);
        Assertion::greaterOrEqualThan($lon, -180.0);
        Assertion::lessOrEqualThan($lon, 180.0);

        $this->lat = $lat;
        $this->lon = $lon;
    }

    public function latitude()
    {
        return $this->lat;
    }

    public function longitude()
    {
        return $this->lon;
    }

    public function __toString()
    {
        return $this->lat . ' ' . $this->lon;
    }

用法:

$location = new \MyApp\ValueObject\Location(24.7, -20.4059);

echo $location->latitude() , ' ' , $location->longitude();

// or simply

echo $location;

答案 3 :(得分:0)

我也要验证纬度和经度,并得到以下结果:

-90.0000 - 90.0000

^-?([0-9]|[1-8][0-9]|90)\.{1}\d{4}$

-180.0000 - 180.0000

^-?([0-9]|[1-9][0-9]|1[0-7][0-9]|180)\.{1}\d{4}$

我已经用pcre测试了here

答案 4 :(得分:0)

这是网络中真正的工作unicum解决方案     “     -90.0000 - 90.0000

^-?([0-9]|[1-8][0-9]|90)\.{1}\d{4}$

-180.0000 - 180.0000

^-?([0-9]|[1-9][0-9]|1[0-7][0-9]|180)\.{1}\d{4}$
"

对于&amp; lat = 90.000000&amp; lon = 180.000000:

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

"/^-?([1]?[1-7][1-9]|[1]?[1-8][0]|[1-9]?[0-9])\.{1}\d{1,6}/"

答案 5 :(得分:0)

正则表达式

/([0-9.-]+).+?([0-9.-]+)/

答案 6 :(得分:0)

验证纬度的功能

 val someIntegerPlus3: Int = f(someInteger)

用于验证经度的功能

function validateLatitude($lat) {


    $lat_array = explode( '.' , $lat );

    if( sizeof($lat_array) !=2 ){
        return '_n_';
    }

    if ( ! ( is_numeric($lat_array[0]) && $lat_array[0]==round($lat_array[0], 0) && is_numeric($lat_array[1]) && $lat_array[1]==round($lat_array[1], 0)  ) ){
        return '_n_';
    }

    if( $lat >= -90 && $lat <= 90 ){
        return '_s_';
    }
    else {
        return '_n_';
    }

}

答案 7 :(得分:0)

这些似乎不太准确:

纬度在 -90 到 90 度之间

经度在 -180 到 90 度之间

正则表达式中的

\d 匹配多于 [0-9]

对于一些正则表达式的整个库似乎也不合逻辑......

所以我构建并测试了:

//Latitude
if(preg_match('/^-?(90|[1-8][0-9][.][0-9]{1,20}|[0-9][.][0-9]{1,20})$/', '89.33333')) {
                            echo "<br>a match<br>"; 
} //will pass ->89.33333


//Longitude
if(preg_match('/^-?(180|1[1-7][0-9][.][0-9]{1,20}|[1-9][0-9][.][0-9]{1,20}|[0-9][.][0-9]{1,20})$/', '180.33333')) {
                            echo "<br>b match<br>"; 
} // will fail anything over 180 ->180.33333