PHP在最后一个数字处拆分字符串,插入一个额外的字符串并合并新字符串

PHP在最后一个数字处拆分字符串,插入一个额外的字符串并合并新字符串

问题描述:

I have build a calculating script that takes seconds and show them in y:d:h:m:s containing labels etc.

eg. 15768012 = 1 year 12 seconds and 27362 = 15 hours 6 minutes 2 seconds.

The script works perfectly, but I would like to look in the string and split it by the last number (not the first) and then insert the word and so that:

15768012 = 1 year AND 12 seconds and 27362 = 15 hours 6 minutes AND 2 seconds.

I can write my script if you need it, but I don't think it will help you solve this question..

let's say that $string = '15 hours 6 minutes 2 seconds' how would you split it and import the text and ?

<?
if (isset($_POST['number'])) {
    $x = $_POST['number'];
} else {
    $x = 54098;
}

// Labels
$lb_y = 'year';
$lb_ys = 'years';
$lb_d = 'day';
$lb_ds = 'days';
$lb_h = 'hour';
$lb_hs = 'hours';
$lb_m = 'minute';
$lb_ms = 'minutes';
$lb_s = 'second';
$lb_ss = 'seconds';
$lb_and = 'and';

//$x = 54098; // Time in seconds - change to $row['time'];

$f = 15768000; // seconds in a year
$d = 43200; // seconds in a day
$t = 3600; // seconds in an hour
$m = 60; // senconds in a minute


// Let's check if it is more than a minute
if ($x >= $m) {

    // More than a minute
    // Let's check if it is more than an hour
    if ($x >= $t) {

        // More than an hour
        // Let's check if it is more than a day
        if($x >= $d) {

            // More than a day
            // Let's check if it is more than a year
            if ($x >= $f) {

                // More than a year
                // Calculate years
                $a = $x / $f;

                // Get everything before the separator '.'
                if (false !== ($cal = strpos($a, '.'))) {
                    $a = substr($a, 0, $cal);
                }

                // $k = what's left
                $k = $x - ($f * $a);

                // Calculate days
                $b = $k / $d;

                // Get everything before the separator '.'
                if (false !== ($cal = strpos($b, '.'))) {
                    $b = substr($b, 0, $cal);
                }

                // $y = what's left
                $y = $k - ($d * $b);

                // Calculate hours
                $c = $y / $t;

                // Get everything before the separator '.'
                if (false !== ($cal = strpos($c, '.'))) {
                    $c = substr($c, 0, $cal);
                }

                // $z = what's left
                $z = $y - ($t * $c);

                // Calculate minutes
                $e = $z / $m;

                // Get everything before the separator '.'
                if (false !== ($cal = strpos($e, '.'))) {
                    $e = substr($e, 0, $cal);
                }

                // $q = what's left
                $q = $z - ($m * $e);

                // Rewrite numbers if below 9
                if ($a <= 9) { $xa = '0'.$a; } else { $xa = $a; }
                if ($b <= 9) { $xb = '0'.$b; } else { $xb = $b; }
                if ($c <= 9) { $xc = '0'.$c; } else { $xc = $c; }
                if ($e <= 9) { $xe = '0'.$e; } else { $xe = $e; }
                if ($q <= 9) { $xq = '0'.$q; } else { $xq = $q; }

                // Rewrite labels
                if ($a <= 1) { $lb_ys = $lb_y; }
                if ($b <= 1) { $lb_ds = $lb_d; }
                if ($c <= 1) { $lb_hs = $lb_h; }
                if ($e <= 1) { $lb_ms = $lb_m; }
                if ($q <= 1) { $lb_ss = $lb_s; }

                // if == 0 - do not show
                $a = $a.' '.$lb_ys.' ';
                if ($b == 0) {$b = '';} else {$b = $b.' '.$lb_ds.' ';}
                if ($c == 0) {$c = '';} else {$c = $c.' '.$lb_hs.' ';}
                if ($e == 0) {$e = '';} else {$e = $e.' '.$lb_ms.' ';}
                if ($q == 0) {$q = '';} else {$q = $q.' '.$lb_ss;}

                echo $xa.':'.$xb.':'.$xc.':'.$xe.':'.$xq;
                echo '<br>'.$a.$b.$c.$e.$q;


            } else {

                // Less than a year - but more than one day
                // Calculate days
                $b = $x / $d;

                // Get everything before the separator '.'
                if (false !== ($cal = strpos($b, '.'))) {
                    $b = substr($b, 0, $cal);
                }

                // $y = what's left
                $y = $x - ($d * $b);

                // Calculate hours
                $c = $y / $t;

                // Get everything before the separator '.'
                if (false !== ($cal = strpos($c, '.'))) {
                    $c = substr($c, 0, $cal);
                }

                // $z = what's left
                $z = $y - ($t * $c);

                // Calculate minutes
                $e = $z / $m;

                // Get everything before the separator '.'
                if (false !== ($cal = strpos($e, '.'))) {
                    $e = substr($e, 0, $cal);
                }

                // $q = what's left
                $q = $z - ($m * $e);

                // Rewrite numbers if below 9
                if ($b <= 9) { $xb = '0'.$b; } else { $xb = $b; }
                if ($c <= 9) { $xc = '0'.$c; } else { $xc = $c; }
                if ($e <= 9) { $xe = '0'.$e; } else { $xe = $e; }
                if ($q <= 9) { $xq = '0'.$q; } else { $xq = $q; }

                // Rewrite labels
                if ($b <= 1) { $lb_ds = $lb_d; }
                if ($c <= 1) { $lb_hs = $lb_h; }
                if ($e <= 1) { $lb_ms = $lb_m; }
                if ($q <= 1) { $lb_ss = $lb_s; }

                // if == 0 - do not show
                $b = $b.' '.$lb_ds.' ';
                if ($c == 0) {$c = '';} else {$c = $c.' '.$lb_hs.' ';}
                if ($e == 0) {$e = '';} else {$e = $e.' '.$lb_ms.' ';}
                if ($q == 0) {$q = '';} else {$q = $q.' '.$lb_ss;}

                echo $xb.':'.$xc.':'.$xe.':'.$xq;
                echo '<br>'.$b.$c.$e.$q;
            }

        } else {

            // Less than a day
            // Calculate hours
            $c = $x / $t;

            // Get everything before the separator '.'
            if (false !== ($cal = strpos($c, '.'))) {
                $c = substr($c, 0, $cal);
            }

            // $z = what's left
            $z = $x - ($t * $c);

            // Calculate minutes
            $e = $z / $m;

            // Get everything before the separator '.'
            if (false !== ($cal = strpos($e, '.'))) {
                $e = substr($e, 0, $cal);
            }

            // $q = what's left
            $q = $z - ($m * $e);

            // Rewrite numbers if below 9
            if ($c <= 9) { $xc = '0'.$c; } else { $xc = $c; }
            if ($e <= 9) { $xe = '0'.$e; } else { $xe = $e; }
            if ($q <= 9) { $xq = '0'.$q; } else { $xq = $q; }

            // Rewrite labels
            if ($c <= 1) { $lb_hs = $lb_h; }
            if ($e <= 1) { $lb_ms = $lb_m; }
            if ($q <= 1) { $lb_ss = $lb_s; }

            // if == 0 - do not show
            $c = $c.' '.$lb_hs.' ';
            if ($e == 0) {$e = '';} else {$e = $e.' '.$lb_ms.' ';}
            if ($q == 0) {$q = '';} else {$q = $q.' '.$lb_ss;}

            echo $xc.':'.$xe.':'.$xq;
            echo '<br>'.$c.$e.$q;

        }

    } else {

        // Less than an hour
        // Calculate minutes
        $e = $x / $m;

        // Get everything before the separator '.'
        if (false !== ($cal = strpos($e, '.'))) {
            $e = substr($e, 0, $cal);
        }

        // $q = what's left
        $q = $x - ($m * $e);

        // Rewrite numbers if below 9
        if ($e <= 9) { $xe = '0'.$e; } else { $xe = $e; }
        if ($q <= 9) { $xq = '0'.$q; } else { $xq = $q; }

        // Rewrite labels
        if ($e <= 1) { $lb_ms = $lb_m; }
        if ($q <= 1) { $lb_ss = $lb_s; }

        // if == 0 - do not show
        $e = $e.' '.$lb_ms.' ';
        if ($q == 0) {$q = '';} else {$q = $q.' '.$lb_ss;}

        echo $xe.':'.$xq;
        echo '<br>'.$e.$q;

    }

} else {

    // Less than a minute
    // Only secounds

    // Rewrite numbers if below 9
    if ($x <= 9) { $xx = '0'.$x; } else { $xx = $x; }

    // Rewrite labels
    if ($x <= 1) { $lb_ss = $lb_s; }

    // if == 0 - do not show
    $x = $x.' '.$lb_ss;

    echo '00:'.$xx;
    echo '<br>'.$x;

}
?>

<form action="" method="post"><input name="number" type="text"><input name="" type="submit" value="Submit"></form>

Thanks everybody for your help.. here is the simplified and done script.. I have a new problem though.. when you type less than 1576 in the field, it writes some different numbers than I want it to...

EDIT: Problem now fixed.. Welcome to use the script :D

<?
if (isset($_POST['number'])) {
    $x = $_POST['number'];
} else {
    $x = 54098;
}

// Labels
$lb_y = 'year';
$lb_ys = 'years';
$lb_d = 'day';
$lb_ds = 'days';
$lb_h = 'hour';
$lb_hs = 'hours';
$lb_m = 'minute';
$lb_ms = 'minutes';
$lb_s = 'second';
$lb_ss = 'seconds';
$lb_and = 'and';

//$x = 54098; // Time in seconds - change to $row['time'];

$f = 15768000; // seconds in a year
$d = 43200; // seconds in a day
$h = 3600; // seconds in an hour
$m = 60; // seconds in a minute

$a = $x / $f;
if (false !== ($cal = strpos($a, 'E-'))) { $a = 0; }
if (false !== ($cal = strpos($a, '.'))) { $a = substr($a, 0, $cal); }
if ($a <= 0) { $a = 0; }
$b = ($x - ($f * $a)) / $d;
if (false !== ($cal = strpos($b, 'E-'))) { $b = 0; }
if (false !== ($cal = strpos($b, '.'))) { $b = substr($b, 0, $cal); }
if ($b <= 0) { $b = 0; }
$c = ($x - ($f * $a) - ($d * $b)) / $h;
if (false !== ($cal = strpos($c, 'E-'))) { $c = 0; }
if (false !== ($cal = strpos($c, '.'))) { $c = substr($c, 0, $cal); }
if ($c <= 0) { $c = 0; }
$e = ($x - ($f * $a) - ($d * $b) - ($h * $c)) / $m;
if (false !== ($cal = strpos($e, '.'))) { $e = substr($e, 0, $cal); }
if ($e <= 0) { $e = 0; }
$q = ($x - ($f * $a) - ($d * $b) - ($h * $c) - ($m * $e));

// Rewrite numbers if below 9
if ($a <= 9) { $xa = '0'.$a; } else { $xa = $a; }
if ($b <= 9) { $xb = '0'.$b; } else { $xb = $b; }
if ($c <= 9) { $xc = '0'.$c; } else { $xc = $c; }
if ($e <= 9) { $xe = '0'.$e; } else { $xe = $e; }
if ($q <= 9) { $xq = '0'.$q; } else { $xq = $q; }

// Rewrite labels
if ($a <= 1) { $lb_ys = $lb_y; }
if ($b <= 1) { $lb_ds = $lb_d; }
if ($c <= 1) { $lb_hs = $lb_h; }
if ($e <= 1) { $lb_ms = $lb_m; }
if ($q <= 1) { $lb_ss = $lb_s; }

// if == 0 - do not show
if ($a == 0) {$a = '';} else {$a = $a.' '.$lb_ys;}
if ($b == 0) {$b = '';} else {$b = $b.' '.$lb_ds;}
if ($c == 0) {$c = '';} else {$c = $c.' '.$lb_hs;}
if ($e == 0) {$e = '';} else {$e = $e.' '.$lb_ms;}
if ($q == 0) {$q = '';} else {$q = $q.' '.$lb_ss;}

echo $xa.':'.$xb.':'.$xc.':'.$xe.':'.$xq.'<br>';

$time = array($a, $b, $c, $e, $q);

$time = array_filter($time);
$count = count($time);
$last = array_pop($time);
if ($count == 1) {
    $string = $last;
} elseif ($count == 0) {
    $string = '<i>No Time described</i>';
} else {
    $string = implode(', ', $time) . ' '.$lb_and.' ' . $last;
}

echo '<br>'.$string;

?>
<br><br>
<form action="" method="post"><input name="number" type="text"><input name="" type="submit" value="Submit"></form>

A quick fix may be:

$string = '15 hours 6 minutes 2 seconds';
$pattern ='/ \d+ \w+$/';
$string = preg_replace($pattern, ' and$0', $string);

However, you may want to look into a nicer solution which resulted in the following array being built:

$time = array($a, $b, $c, $e, $q);

You could then do:

$time = array_filter($time);
$last = array_pop($time);
$string = implode(', ', $time) . ' and ' . $last;

As what you've already achieved is relatively complex, I assume you only need some hints; so:

  • explode function: http://php.net/manual/en/function.explode.php
  • as you know your string ends with a number and its units, ignore the last 2 elements of the array produced by explode
  • loop (in whatever way you see fit, not necessarily a traditional for loop) through the array and add 'and' in.

It would be more efficient if you build it directly in your function , but in the meantime you can use preg_replace.

http://nl3.php.net/manual/en/function.preg-replace.php

$string = '15 hours 6 minutes 2 seconds'

$pattern ='/(\d+)\sseconds/';

$string =preg_replace($pattern,' And $1 seconds',$string);

That looks rather long and tedious, when you could use the division to help figure out the values as you go. That way, you can then do logic on them one at a time (to figure out if they need (s) on the end or not.

$x / $f = $years
($x - ($f * $years)) / $d = $days
($x - ($f * $years) - ($d * $days)) / $h = $hours
($x - ($f * $years) - ($d * $days) - ($h * $hours)) / $m = $minutes
($x - ($f * $years) - ($d * $days) - ($h * $hours) - ($m * $minutes)) = $seconds

Basically as it goes, it figures out how much is left of the remainder of each of the previous calculations. Simple example is if your number is 1 second bigger then 2 years.

Years would give 2, with 1 remainder. You subtract away the portion you already accounted for and keep dividing up into smaller sections as you go. This way, you can handle each individual number easier for formatting purposes.