根据匹配结果在一步内替换


Replace in one step based on matched result

我有一个字符串,我希望每个YYYY-MM-DD HH:MM:SS日期时间字符串替换为unix时间戳。

我已经设法尽可能地确定日期时间字符串发生的位置:

$my_string = 'Hello world 2014-12-25 10:00:00 and foo 2014-09-10 05:00:00, bar';
preg_match_all('((?:2|1)''d{3}(?:-|''/)(?:(?:0[1-9])|(?:1[0-2]))(?:-|''/)(?:(?:0[1-9])|(?:[1-2][0-9])|(?:3[0-1]))(?:T|''s)(?:(?:[0-1][0-9])|(?:2[0-3])):(?:[0-5][0-9]):(?:[0-5][0-9]))',$my_string,$my_matches, PREG_OFFSET_CAPTURE);
print_r($my_matches);

输出一个数组,其中包含匹配的日期时间字符串的值及其位置:

Array
(
    [0] => Array
        (
            [0] => Array
                (
                    [0] => 2014-12-25 10:00:00
                    [1] => 12
                )
            [1] => Array
                (
                    [0] => 2014-09-10 05:00:00
                    [1] => 40
                )
        )
)

从这里开始,我将循环遍历数组并根据str_replace()strtotime()进行替换,但是我认为如果我能做这样的事情,执行时间会更短:

$my_string = preg_replace(
    '((?:2|1)''d{3}(?:-|''/)(?:(?:0[1-9])|(?:1[0-2]))(?:-|''/)(?:(?:0[1-9])|(?:[1-2][0-9])|(?:3[0-1]))(?:T|''s)(?:(?:[0-1][0-9])|(?:2[0-3])):(?:[0-5][0-9]):(?:[0-5][0-9]))',
    strtotime($VALUE_OF_MATCHED_STRING),
    $my_string
);

因此,每个找到的匹配实例将被简单地转换为strtotime()格式。

得到这个结果的正确方法是什么?循环是最可行的方法吗?

使用preg_replace_callback()代替。它允许您使用回调函数执行搜索和替换:

echo preg_replace_callback($pattern, function ($m) {
    return strtotime($m[0]);
}, $my_string);

$m是包含匹配项的数组。$m[0]包含日期字符串。

上面的代码将输出:
Hello world 1419501600 and foo 1410325200, bar