64048


緯度経度のバリデーションに正規表現を使おうと思っています。  
また、前提条件としてはphpのpreg_matchを使用します。

条件が  
1\. 値が-180から180の範囲である。  
2．実数部は6桁まで  
3．ゼロ埋めは許容

ご教授ください。


CC BY-SA 4.0
2020-03-23T09:58:57.393
64043
2020-03-23T14:04:16.583
2020-03-23T12:32:28.397
35558
34792
question
php 正規表現
緯度経度を正規表現でチェックする方法（php preg_match）


**【回答】**

>   1. 値が-180から180の範囲である。
>

を正規表現でチェックするのは無理そうです。

`2.`と`3`ならば以下でよいと思います。

[code]

    /\A[-]?[0-9]{1,3}\.[0-9]{1,6}\z/u
    
[/code]

※ 整数部3桁、小数点以下桁数6桁

**【確認方法】**

動作の確認は以下のツールで行いました。  
[PHP: preg_match() / JavaScript: match() 正規表現チェッカー
ver3.1](http://okumocchi.jp/php/re.php)


CC BY-SA 4.0
2020-03-23T10:27:46.493
64044
2020-03-23T12:54:00.233
2020-03-23T12:54:00.233
35558
35558
64043
answer


6桁という条件が微妙ですが、

[code]

    OK: 180 180.000 180.00 180.0 090.000 009.000
    NG: 180.001  90.0000 0.11111 0.
    
[/code]

と解釈しました。

[code]

    /\A-?(180(\.0{1,3})?|(1[0-7]\d|0?\d{2}|0?0?\d)(\.\d{1,3})?)\z/
    
[/code]

こうでしょうか。(テストしてません)

非常にわかりにくいので、

  * 正規表現ではフォーマットのチェック
  * 範囲内かどうかは数値に変換して比較

にした方がよいでしょう


CC BY-SA 4.0
2020-03-23T12:29:38.977
64048
2020-03-23T12:29:38.977
5793
64043
answer


[preg_replace_callback()](https://www.php.net/manual/en/function.preg-replace-
callback.php) を使う方法も考えられます。具体的には、`preg_replace_callback()` の callback function
内で `preg_match()` を使用します。

以下のコードでは、callback function は boolean value を返していますが、これは自動的に文字列(string
type)に変換されます(`true`=>`"1"`, `false`=>`""` へ変換)。

[code]

    <?php
    
    $long_lat_values = [
      '',           // ng(empty string)
      '0',          // ok
      '0.0',        // ok
      '012.3',      // ok
      '124.456',    // ok
      '-45.2',      // ok
      '240',        // ng
      '-360.02',    // ng
      '10.123456',  // ok
      '10.1234567'  // ng
    ];
    
    foreach ($long_lat_values as $v) {
      $result = preg_replace_callback('/^.+$/',
        function($m) {
          if (preg_match('/^[-+]?\d{1,3}(\.\d{1,6})?$/', $m[0], $match)) {
            $n = floatval($match[0]);
            return (-180.0 <= $n && $n <= 180.0) ? true : false;
          }
          return false;
        }, $v);
    
      printf("%10s is %s\n", $v, ($result ? 'ok' : 'ng'));
    }
    
[/code]


CC BY-SA 4.0
2020-03-23T14:04:16.583
64054
2020-03-23T14:04:16.583
64043
answer