PHP预匹配常量输出

PHP预匹配常量输出,php,arrays,preg-match,Php,Arrays,Preg Match,我试图解析出一个可能有多个值的字符串,如果其中一个值不存在,那么数组将输出我要查找的部分,这让我在逻辑上很头疼 我试图解析的内容:P1DT12H15M,或PT1H5M,或PT15M 基本上是P(天数)T(小时数)(分钟数)。P和T是常数。这是我到目前为止的匹配字符串: '/P([0-9]*?)D?T([1-2]?[0-9]?)H?([1-5]?[0-9]?)M?/' 它将所有内容分离开来,但阵列输出不是我想要的 PT2H gives Array ( [0] => PT2H [1] =&g

我试图解析出一个可能有多个值的字符串,如果其中一个值不存在,那么数组将输出我要查找的部分,这让我在逻辑上很头疼

我试图解析的内容:
P1DT12H15M
,或
PT1H5M
,或
PT15M
基本上是P(天数)T(小时数)(分钟数)。P和T是常数。这是我到目前为止的匹配字符串:

'/P([0-9]*?)D?T([1-2]?[0-9]?)H?([1-5]?[0-9]?)M?/'
它将所有内容分离开来,但阵列输出不是我想要的

PT2H gives Array ( [0] => PT2H [1] => [2] => 2 [3] => )
PT2H15M gives Array ( [0] => PT2H15M [1] => [2] => 2 [3] => 15 )
但是

如果可能的话,我需要那个号码在第三位

$exp = '/P(?:([0-9]+)D)*T(?:([1-2]?[0-9])H)*(?:([1-5]?[0-9])M)*/';

preg_match($exp, 'PT2H15M', $m); print_r($m);
preg_match($exp, 'PT15M', $m); print_r($m);
preg_match($exp, 'P1DT12H15M',$m); print_r($m);
结果

Array
(
    [0] => PT2H15M
    [1] => 
    [2] => 2
    [3] => 15
)
Array
(
    [0] => PT15M
    [1] => 
    [2] => 
    [3] => 15
)
Array
(
    [0] => P1DT12H15M
    [1] => 1
    [2] => 12
    [3] => 15
)

因此,您可以使用
$p=m[1]、$H=m[2]、$m=m[3]

您的输入字符串看起来像时间间隔说明符。让PHP内部类解析它们,然后访问[
DateInterval
]的属性以获取所需的值:

$int = new DateInterval('P1DT12H15M');
print_r($int);
产生:

DateInterval Object
(
    [y] => 0
    [m] => 0
    [d] => 1
    [h] => 12
    [i] => 15
    [s] => 0
    [weekday] => 0
    [weekday_behavior] => 0
    [first_last_day_of] => 0
    [invert] => 0
    [days] =>
    [special_type] => 0
    [special_amount] => 0
    [have_weekday_relative] => 0
    [have_special_relative] => 0
)
您可以直接访问这些属性(它们是公共的):

如果需要将它们作为数组,您甚至可以将
$int
转换为
数组
,并以以下方式使用它们:

$date = (array)$int;
printf("%d days, %d hours, %d minutes\n", $date['d'], $date['h'], $date['i']);
如果您坚持,您甚至可以模拟您努力创建的
preg\u match()
的行为:

$string   = 'P1DT12H15M';
$interval = new DateInterval($string);
$array    = (array)$interval;
$matches  = array_merge(array($string), array_slice(array_values($array), 0, 6));

print_r($matches);
显示:

Array
(
    [0] => P1DT12H15M
    [1] => 0
    [2] => 0
    [3] => 1
    [4] => 12
    [5] => 15
    [6] => 0
)

(使用
array\u slice(…,3,6)
仅保留时间组件)

如何处理这些值?为什么不使用PHP日期对象?
$string   = 'P1DT12H15M';
$interval = new DateInterval($string);
$array    = (array)$interval;
$matches  = array_merge(array($string), array_slice(array_values($array), 0, 6));

print_r($matches);
Array
(
    [0] => P1DT12H15M
    [1] => 0
    [2] => 0
    [3] => 1
    [4] => 12
    [5] => 15
    [6] => 0
)