douke7431 2019-04-22 02:48
浏览 49
已采纳

需要帮助如何使用preg_replace_callback

I have this code which returns:

float(-70.869444444444)

I can see using var_dump that it finds all coordinates, but only one is displayed.

How do I modify below code to display all coordinates transferred to degree format and also display text?

Wanted result should be:

-70.869 -6.35 test -127.49 more test second line -127.35

Code

$str60 = 'W07052 W0623 test E12727 more test second line E12725';

preg_match_all('/([EWSN])([0-9]{3})([0-9]{2})/ms', $str60, $matches);
$result60 = DMS2Decimal($degrees = (int) $matches[2][0], $minutes = (int) $matches[3][0], $seconds = 10, $direction = strtolower($matches[1][0]));


function DMS2Decimal($degrees = 0, $minutes = 0, $seconds = 0, $direction = 'n')
{
//converts DMS coordinates to decimal
//returns false on bad inputs, decimal on success

//direction must be n, s, e or w, case-insensitive
$d = strtolower($direction);
$ok = array('n', 's', 'e', 'w');

//degrees must be integer between 0 and 180
if (!is_numeric($degrees) || $degrees < 0 || $degrees > 180) {
    $decimal = false;
    //var_dump($decimal);
}
//minutes must be integer or float between 0 and 59
elseif (!is_numeric($minutes) || $minutes < 0 || $minutes > 59) {
    $decimal = false;
    //var_dump($decimal);
}
//seconds must be integer or float between 0 and 59
elseif (!is_numeric($seconds) || $seconds < 0 || $seconds > 59) {
    $decimal = false;
} elseif (!in_array($d, $ok)) {
    $decimal = false;
    //var_dump($decimal);
} else {
    //inputs clean, calculate
    $decimal = $degrees + ($minutes / 60) + ($seconds / 3600);

    //reverse for south or west coordinates; north is assumed
    if ($d == 's' || $d == 'w') {
        $decimal *= -1;
    }
}

return $decimal;
}

var_dump($matches);
var_dump($result60);
  • 写回答

2条回答 默认 最新

  • duansengcha9114 2019-04-22 03:57
    关注

    Yes, preg_replace_callback is what you want. I tweaked your regular expression as I assumed you wanted to catch"W0623."

    I also cleaned up your function a bit, though the only change in output was to round it to 3 decimal places. The rest was just organizing your conditions and can be ignored if you prefer.

    function DMS2Decimal($degrees = 0, $minutes = 0, $seconds = 0, $direction = 'n')
    {
        //converts DMS coordinates to decimal
        //returns false on bad inputs, decimal on success
    
        $d = strtolower($direction);
        if (
            //degrees must be integer between 0 and 180
            (is_numeric($degrees) && $degrees >= 0 && $degrees <= 180) &&
            //minutes must be integer or float between 0 and 59
            (is_numeric($minutes) && $minutes >= 0 && $minutes <= 59) &&
            //seconds must be integer or float between 0 and 59
            (is_numeric($seconds) && $seconds >= 0 && $seconds <= 59) &&
            //direction must be n, s, e or w, case-insensitive
            (in_array($d, ['n', 's', 'e', 'w']))
        ) {
            $decimal = $degrees + ($minutes / 60) + ($seconds / 3600);        
            //reverse for south or west coordinates; north is assumed
            if ($d == 's' || $d == 'w') {
                $decimal *= -1;
            }
            return round($decimal, 3);
        } else {
            return false;
        }
    }
    
    $str60 = 'W07052 W0623 test E12727 more test second line E12725';
    $result60 = preg_replace_callback(
        "/([EWSN])([0-9]{3})([0-9]{1,2})/ms",
        function($m) {return DMS2Decimal((int)$m[2], (int)$m[3], 10, $m[1]);},
        $str60
    );
    echo $result60;
    

    Output:

    -70.869 -62.053 test 127.453 more test second line 127.419
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器