如何转换" 1d2h3m"到阵列("日" => 1,“小时”=> 2,"分钟" => 3)?

时间:2015-09-22 04:05:34

标签: php arrays date

$time = "1d2h3m";所以我希望这个像array("day" => 1, ”hour” => 2,"minutes"=>3)这样的数组,所以我试过通过explode()

<?php
   $time = "1d2h3m";
   $day = explode("d", $time);
   var_dump($day); // 0 => string '1' (length=1)
                   // 1 => string '2h3m' (length=4)
?>

这里我不知道如何做像array("day" => 1, ”hour” => 2,"minutes"=>3)

这样的数组

17 个答案:

答案 0 :(得分:25)

一个简单的sscanf会将其解析为一个数组。然后使用您想要的键列表array_combine

实施例

$time = "1d2h3m";

$result = array_combine(
    ['day', 'hour', 'minutes'],
    sscanf($time, '%dd%dh%dm')
);

print_r($result);

输出:

Array
(
    [day] => 1
    [hour] => 2
    [minutes] => 3
)

要细分使用的sscanf格式:

  • %d - 读取(带符号)十进制数,输出整数
  • d - 匹配文字字符“d”
  • %d - (作为第一个)
  • h - 匹配文字字符“h”
  • %d - (作为第一个)
  • m - 匹配文字字符“m”(可选,因为它出现在您想要抓取的所有内容之后)

它也适用于多位数和负值:

$time = "42d-5h3m";
Array
(
    [day] => 42
    [hour] => -5
    [minutes] => 3
)

答案 1 :(得分:16)

你应该使用正则表达式来处理这种情况

<?php
 $time = "1d2h3m";
 if(preg_match("/([0-9]+)d([0-9]+)h([0-9]+)m/i",$time,$regx_time)){
    $day = (int) $regx_time[1];
    $hour = (int) $regx_time[2];
    $minute = (int) $regx_time[3];
    var_dump($day);
 }
?>

解释:
[0-9] :匹配0到9之间的任何数字 [0-9] + :表示匹配数字至少一个字符
([0-9] +):表示匹配至少一个字符的数字并捕获结果
/........../ i :为您设置的正则表达式设置不区分大小写

正则表达式更好地成为词法分析器和词法分析字符串。学习正则表达式很好。几乎所有编程语言都使用正则表达式

答案 2 :(得分:12)

可自定义的功能,最重要的是,如果输入未正确形成,您可以捕获异常

/**
  * @param $inputs string : date time on this format 1d2h3m
  * @return array on this format                 "day"      => 1,
  *                                              "hour"     => 2,
  *                                              "minutes"  => 3        
  * @throws Exception
  *
  */
function dateTimeConverter($inputs) {
    // here you can customize how the function interprets input data and how it should return the result
    // example : you can add "y"    => "year"
    //                       "s"    => "seconds"
    //                       "u"    => "microsecond"
    // key, can be also a string
    // example                "us"  => "microsecond"
    $dateTimeIndex  = array("d" => "day",
                               "h" => "hour",
                               "m" => "minutes");

    $pattern        = "#(([0-9]+)([a-z]+))#";
    $r              = preg_match_all($pattern, $inputs, $matches);
    if ($r === FALSE) {
        throw new Exception("can not parse input data");
    }
    if (count($matches) != 4) {
        throw new Exception("something wrong with input data");
    }
    $datei      = $matches[2]; // contains number
    $dates      = $matches[3]; // contains char or string
    $result    = array();
    for ($i=0 ; $i<count ($dates) ; $i++) {
        if(!array_key_exists($dates[$i], $dateTimeIndex)) {
            throw new Exception ("dateTimeIndex is not configured properly, please add this index : [" . $dates[$i] . "]");
        }
        $result[$dateTimeIndex[$dates[$i]]] = (int)$datei[$i];
    }
    return $result;
}

答案 3 :(得分:5)

另一种正则表达式解决方案

$subject = '1d2h3m';
if(preg_match('/(?P<day>\d+)d(?P<hour>\d+)h(?P<minute>\d+)m/',$subject,$matches))
{
  $result = array_map('intval',array_intersect_key($matches,array_flip(array_filter(array_keys($matches),'is_string'))));
  var_dump($result);
}

返回

array (size=3)
  'day' => int 1
  'hour' => int 2
  'minute' => int 3

答案 4 :(得分:5)

将此简单实现与字符串替换和数组合并使用。

<?php
   $time = "1d2h3m";
   $time=str_replace(array("d","h","m")," " ,$time);
   $time=array_combine(array("day","hour","minute"),explode(" ",$time,3));

   print_r($time);
?>

答案 5 :(得分:4)

我认为对于这么小的字符串,如果格式总是相同的,你可以使用array_pushsubstr从字符串中提取数字并将它们放在一个数组中

<?php
$time = "1d2h3m";
$array = array();
array_push($array, (int) substr($time, 0, 1));
array_push($array, (int) substr($time, 2, 1));
array_push($array, (int) substr($time, 4, 1));
var_dump($array);
?>

答案 6 :(得分:3)

此方法使用正则表达式提取值,使用数组将字母映射到单词。

<?php
   // Initialize target array as empty
   $values = [];

   // Use $units to map the letters to the words
   $units = ['d'=>'days','h'=>'hours','m'=>'minutes'];

   // Test value
   $time = '1d2h3m';

   // Extract out all the digits and letters
   $data = preg_match_all('/(\d+)([dhm])/',$time,$matches);

   // The second (index 1) array has the values (digits)
   $unitValues = $matches[1];

   // The third (index 2) array has the keys (letters)
   $unitKeys = $matches[2];

   // Loop through all the values and use the key as an index into the keys
   foreach ($unitValues as $k => $v) {
       $values[$units[$unitKeys[$k]]] = $v;
   }

答案 7 :(得分:3)

$d = [];
list($d['day'],$d['hour'],$d['minutes']) = preg_split('#[dhm]#',"1d2h3m");

答案 8 :(得分:0)

你不能爆炸它3次......

// Define an array
$day = explode("d", $time);
// add it in array with key as "day" and first element as value
$hour= explode("h", <use second value from above explode>);
// add it in array with key as "hour" and first element as value
$minute= explode("m", <use second value from above explode>);
// add it in array with key as "minute" and first element as value

我现在没有任何工作实例,但我认为它会奏效。

答案 9 :(得分:0)

我们可以同时使用str_replace()explode()功能实现这一目标。

$time = "1d2h3m"; 
$time = str_replace(array("d","h","m"), "*", $time);
$exp_time =  explode("*", $time); 
$my_array =  array(  "day"=>(int)$exp_time[0],
                     "hour"=>(int)$exp_time[1],
                     "minutes"=>(int)$exp_time[2] ); 
var_dump($my_array);

答案 10 :(得分:0)

$time = "1d2h3m";
$split = preg_split("/[dhm]/",$time);
$day = array(
    "day"     => $split[0]
    "hour"    => $split[1]
    "minutes" => $split[2]
);

答案 11 :(得分:0)

您可以使用一行解决方案

$time = "1d2h3m";
$day = array_combine(
           array("day","hour","months")   , 
           preg_split("/[dhm]/", substr($time,0,-1)  )    
       );

答案 12 :(得分:0)

这里有很多很棒的答案,但我想再添加一个,以显示更通用的方法。

function parseUnits($input, $units = array('d'=>'days','h'=>'hours','m' => 'minutes')) {
    $offset = 0;
    $idx = 0;

    $result = array();
    while(preg_match('/(\d+)(\D+)/', $input,$match, PREG_OFFSET_CAPTURE, $offset)) {
        $offset = $match[2][1];

        //ignore spaces
        $unit = trim($match[2][0]);
        if (array_key_exists($unit,$units)) { 
            // Check if the unit was allready found
            if (isset($result[$units[$unit]])) {  
                throw new Exception("duplicate unit $unit");
            }

            // Check for corect order of units
            $new_idx = array_search($unit,array_keys($units));
            if ($new_idx < $idx) {
                throw new Exception("unit $unit out of order");             
            } else {
                $idx = $new_idx;
            }
            $result[$units[trim($match[2][0])]] = $match[1][0];

        } else {
            throw new Exception("unknown unit $unit");
        }
    }
    // add missing units
    foreach (array_keys(array_diff_key(array_flip($units),$result)) as $key) {
        $result[$key] = 0;
    }
    return $result;
}
print_r(parseUnits('1d3m'));
print_r(parseUnits('8h9m'));
print_r(parseUnits('2d8h'));
print_r(parseUnits("3'4\"", array("'" => 'feet', '"' => 'inches')));
print_r(parseUnits("3'", array("'" => 'feet', '"' => 'inches')));
print_r(parseUnits("3m 5 d 5h 1M 10s", array('y' => 'years', 
           'm' => 'months', 'd' =>'days', 'h' => 'hours', 
           'M' => 'minutes', "'" => 'minutes', 's' => 'seconds' )));
print_r(parseUnits("3m 5 d 5h 1' 10s", array('y' => 'years', 
           'm' => 'months', 'd' =>'days', 'h' => 'hours',
           'M' => 'minutes', "'" => 'minutes', 's' => 'seconds' )));

答案 13 :(得分:0)

您可以使用此fn来获取格式化的数组,该数组也会检查字符串验证:

function getFormatTm($str)
{
    $tm=preg_split("/[a-zA-z]/", $str);

    if(count($tm)!=4) //if not a valid string
       return "not valid string<br>";
    else
       return array("day"=>$tm[0],"hour"=>$tm[1],"minutes"=>$tm[2]);
}
$t=getFormatTm("1d2h3m");
var_dump($t);

答案 14 :(得分:0)

此答案与问题中的特定输入字符串格式不是100%相关。

但它基于 PHP日期解析机制(不是我自己的日期解析自行车)。

  

PHP&gt; = 5.3.0有DateInterval类。

您可以使用两种格式从stings创建DateInterval对象:

$i = new DateInterval('P1DT12H'); // ISO8601 format
$i = createFromDateString('1 day + 12 hours'); // human format

PHP官方文档:http://php.net/manual/en/dateinterval.createfromdatestring.php

在ISO8601格式中,P代表&#34;句号&#34;。格式支持三种形式的句点:

  • PnYnMnDTnHnMnS
  • PNW
  • PT

大写字母代表以下内容:

  • P是在持续时间表示开始时放置的持续时间指示符(历史上称为&#34;句号&#34;)。
  • Y是年份指示符,它遵循年数值。
  • M是月份指示符,它遵循月数值。
  • W是星号指示符,它跟随数字的值 周。
  • D是指示数量值的日期指示符 天。
  • T是时间指示符,位于时间分量之前 表示。
  • H是小时指示符,它跟随数字的值 小时。
  • M是遵循数量值的分钟指示符 分钟。
  • S是第二个指示符,它遵循数字的值 秒。
  

例如,&#34; P3Y6M4DT12H30M5S &#34;表示持续时间为&#34; 三年,   六个月,四天,十二小时,三十分钟和五个月   秒&#34;

有关详细信息,请参阅https://en.wikipedia.org/wiki/ISO_8601#Durations

答案 15 :(得分:0)

一行代码。

   $result = array_combine(array("day", "hour", "minutes"), $preg_split('/[dhm]/', "1d2h3m", -1, PREG_SPLIT_NO_EMPTY));

答案 16 :(得分:-2)

您可以使用此代码。

<?php
$str = "1d2h3m";
list($arr['day'],$arr['day'],$arr['hour'],$arr['hour'],$arr['minute'],$arr['minute']) = $str;
print_r($arr);
?>
  

输出

Array ( 
   [minute] => 3
   [hour] => 2
   [day] => 1
)

DEMO