PHP 在保留分隔符的情况下按日期展开

PHP explode by date while keeping delimitter

我的字符串看起来像这样05/21/2018 ghijkl 06/12/2018 mnopqrst

我需要提取每个日期之后的所有值并包括日期。我试过了

explode('/2018', $string);

但这会把日期分开,而且也不是面向未来的。我在想必须有一种方法可以在元素中包含分隔符。也许还有一个我应该用来查找日期的正则表达式?

谢谢。

您可以使用current(explode('/', $string));

假设您的日期保证按照您提到的格式进行格式化(如果它是用户输入的数据,那么假设通常是不安全的),您可以使用正则表达式来查找日期后的字符串:

使用 PHP 正则表达式拆分为以下表达式: /([0-9]{1,2}\/[0-9]{1,2}\/[0-9]{2,4})([a-zA-Z\s]+)/g

05/21/2018 ghijkl 10/12/2017 mnopqrst 分成不同组的数组。根据您实际想要输出数据的方式,您可以在一个匹配组中捕获日期和后续字符串。

示例代码:

$string = '05/21/2018 ghijkl 10/12/2017 mnopqrst';
preg_split('/([0-9]{1,2}\/[0-9]{1,2}\/[0-9]{2,4})([a-zA-Z\s]+)/g', $string, $stringParts);

array (
    0 => '05/21/2018', 
    1 => 'ghijkl',
    2 => '10/12/2017',
    3 => 'mnopqrst'
);

https://regex101.com/r/gPXkDz/2

你可以这样做

$str = '05/21/2018 ghijkl 10/12/2017 mnopqrst';
$arr = explode(' ',$str);
$new = array();
for($i=0;$i<count($arr);$i+=2){
  $new[] = ["date"=>$arr[$i],"value"=>$arr[$i+1]];
}
print_r($new);

Live Demo

输出:

Array
(
    [0] => Array
        (
            [date] => 05/21/2018
            [value] => ghijkl
        )

    [1] => Array
        (
            [date] => 10/12/2017
            [value] => mnopqrst
        )

)

您可以使用正则表达式来做到这一点。这是一个示例代码:

<?php

$string = '05/21/2018 ghijkl 06/12/2018 mnopqrst';
$matches = [];

if (preg_match_all('#(\d{2}\/\d{2}\/\d{4})#i', $string, $matches) > 0) {
  echo "Found the following dates: \n";

  foreach ($matches[0] as $date) {
    printf("- %s\n", $date);
  }
}

这将导致以下输出:

Found the following dates:
- 05/21/2018
- 06/12/2018

您可以将 preg_splitPREG_SPLIT_DELIM_CAPTUREPREG_SPLIT_NO_EMPTY 标志一起使用,以保留分隔符并从结果数组中删除空值。

您可能会使用与日期格式相匹配的模式 \b\d{1,2}/\d{1,2}/\d{4}\b (请注意 它与示例数据中的日期格式相匹配,而不是验证日期本身)

例如:

$str = '05/21/2018 ghijkl 06/12/2018 mnopqrst';
$result = preg_split('@(\b\d{1,2}/\d{1,2}/\d{4}\b)@', $str, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
var_dump($result);

Demo

要验证日期,您可以使用 DateTime and perhaps specify your format using createFromFormat

$date = DateTime::createFromFormat("m/d/Y", '05/21/2018');