【问题标题】:Need help how to use preg_replace_callback需要帮助如何使用 preg_replace_callback
【发布时间】:2019-04-22 02:48:45
【问题描述】:

我有这个返回的代码:

float(-70.869444444444)

我可以看到使用var_dump 找到所有坐标,但只显示一个。

如何修改以下代码以显示转换为度数格式的所有坐标并显示文本?

想要的结果应该是:

-70.869 -6.35 测试-127.49 再测试第二行-127.35

代码

$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);

【问题讨论】:

  • 非常感谢,完美运行。

标签: php regex


【解决方案1】:

是的,preg_replace_callback 就是您想要的。我假设你想捕捉“W0623”,所以我调整了你的正则表达式。

我还稍微清理了您的函数,但输出的唯一变化是将其四舍五入到小数点后 3 位。其余的只是组织你的条件,如果你愿意,可以忽略。

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;

输出:

-70.869 -62.053 test 127.453 more test second line 127.419

【讨论】:

    【解决方案2】:

    下面的脚本可能会返回您想要的结果。我不确定我是否为函数提供了正确的输入值,它基于this,其中NWSE 是方向,下一个{2}digits 可能是Degree,之后的{2} 数字可能是Minute,其余数字可能是Second,它可能是也可能不是浮点数。

    $str60 = 'N404536 W73592.4 test E73592.4 more test second line S73592.4';
    $split_strings = preg_split('/\s/s', $str60);
    foreach ($split_strings as $value) {
        if (preg_match('/([EWSN][0-9\.]{4,})/ms', $value)) {
            $result60 .= DMS2Decimal(
                $degrees = (int) substr($value, 1, 2), // Not sure, this might return degrees - e.g., W{73}592.4
                $minutes = (int) substr($value, 3, 2), // Not sure, this might return minutes - e.g., W735{92}.4
                $seconds = substr($value, 5) != null ? (int) substr($value, 5) : 0, // Not sure, this checks if second is available or place zero - e.g., W7359{2.4}
                $direction = substr($value, 0, 1) // This is direction East West North South - e.g., {W}73592.4
            ) . " ";
        } else {
            $result60 .= $value . " ";
        }
    
    }
    var_dump($result60);
    
    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;
    }
    

    输出

     string(56) "40.76 -73.984 test 73.984 more test second line -73.984 "
    

    【讨论】:

      猜你喜欢
      • 2017-08-31
      • 2014-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-06
      • 1970-01-01
      • 2020-08-26
      相关资源
      最近更新 更多