【问题标题】:How to split string with date as delimiter?如何以日期为分隔符拆分字符串?
【发布时间】:2013-06-04 09:54:25
【问题描述】:

你能帮我把大字符串分成子字符串吗?

场景: 在 MySQL 表中的一个字段中,我有一个字符串,其中有一个以下格式的活动日志:

yyyy-mm-dd hh:mm:ss - Name1 Surname1 - Activity1
yyyy-mm-dd hh:mm:ss - Name2 Surname2 - Activity2
yyyy-mm-dd hh:mm:ss - Name3 Surname3 - Multiline Activity1
Multiline Activity2
Multiline Activity3
yyyy-mm-dd hh:mm:ss - Name4 Surname4 - Activity4

问题:

如何将上述数据拆分成这样的数组:

id       date                    name                    activity
1        yyyy-mm-dd hh:mm:ss     Name1 Surname1          Activity1
2        yyyy-mm-dd hh:mm:ss     Name2 Surname2          Activity2
3        yyyy-mm-dd hh:mm:ss     Name3 Surname3          Multiline Activity 1, Multiline Activity2, Multiline Activity 3
4        yyyy-mm-dd hh:mm:ss     Name4 Surname4          Activity4

使用 PHP 或 MySQL 查询?

我知道它可以以某种方式完成,但不幸的是,由于 PHP/MySQL 的知识不允许我解析带有可变分隔符(日期)的文本,或者可能有其他方法?

【问题讨论】:

  • 你为什么不在'-'上分开?
  • 即使使用 mysql 也可以做到。检查这个很好的答案:stackoverflow.com/questions/6152137/mysql-string-split 但是,这是高级程序员的高级用法:)
  • 我认为你的表格设计是错误的。你可以在php中使用explode函数来获得所需的输出
  • 不幸的是,我正在处理现有数据库,所以我不是数据结构的设计者。这个问题与将来将数据结构转换为更易于访问的格式有关

标签: php mysql


【解决方案1】:

你可以试试preg_split

$string = <<<STR
2013-06-04 12:12:12 - Name1 Surname1 - Activity1
2013-06-04 12:12:12 - Name2 Surname2 - Activity2
2013-06-04 12:12:12 - Name3 Surname3 - Multiline Activity1
Multiline Activity2
Multiline Activity3
2013-06-04 12:12:12 - Name4 Surname4 - Activity4
STR;

$arr = preg_split("/(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) - (.*) - (.*)[\r\n]?/", $string, null, PREG_SPLIT_DELIM_CAPTURE);

$arr = array_filter($arr);

print_r($arr);

输出:

Array
(
    [1] => 2013-06-04 12:12:12
    [2] => Name1 Surname1
    [3] => Activity1
    [5] => 2013-06-04 12:12:12
    [6] => Name2 Surname2
    [7] => Activity2
    [9] => 2013-06-04 12:12:12
    [10] => Name3 Surname3
    [11] => Multiline Activity1
    [12] => Multiline Activity2
Multiline Activity3

    [13] => 2013-06-04 12:12:12
    [14] => Name4 Surname4
    [15] => Activity4
)

实际使用示例:

$i = -1; 
$result = array();

foreach($arr as $value) {
    if(preg_match("/(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})/", $value)) {
        // 1st element - datetime
        $i++;
        $result[$i]['datetime'] = $value;
    } elseif(!isset($result[$i]['name'])) {
        // 2nd element - name
        $result[$i]['name'] = $value;
    } else {
        // 3rd element - activities separated by comma
        if(!isset($result[$i]['activities'])) {
            $result[$i]['activities'] = $value;
        } else {
            $result[$i]['activities'] .= ', ' . $value;        
        }
    }
}

print_r($result);

输出:

Array
(
    [0] => Array
        (
            [datetime] => 2013-06-04 12:12:12
            [name] => Name1 Surname1
            [activities] => Activity1
        )

    [1] => Array
        (
            [datetime] => 2013-06-04 12:12:12
            [name] => Name2 Surname2
            [activities] => Activity2
        )

    [2] => Array
        (
            [datetime] => 2013-06-04 12:12:12
            [name] => Name3 Surname3
            [activities] => Multiline Activity1
, Multiline Activity2
Multiline Activity3

        )

    [3] => Array
        (
            [datetime] => 2013-06-04 12:12:12
            [name] => Name4 Surname4
            [activities] => Activity4
        )

)

【讨论】:

  • 谢谢,这正是我一直在寻找的!干杯,祝你有美好的一天先生;)
【解决方案2】:

遍历 MySQL 结果并对每一行执行以下操作:

$row = explode(' - ', $row);

【讨论】:

  • 此解决方案的问题:名称可能带有连字符,例如约翰-多伊。 Activity 包含一些未知的字符集(对我们而言)。
  • @BLaZuRE 你怎么知道的?
  • 我为最坏的情况编写代码,所以我指出了潜在的问题而不是投反对票。
  • 谢谢,但@BLaZuRE 明白了这一点......活动通常是多行文本,每个字符(及其组合)都可能
猜你喜欢
  • 2014-06-29
  • 2011-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-10
相关资源
最近更新 更多