MySQL在SELECT中提取了几个子串,任意次数

时间:2016-10-04 08:11:58

标签: mysql regex substr

所以我项目的前一个编码器决定将PHP-seralized信息放在MySQL数据库中,如下所示:

a:2:{s:6:"Format";s:4:"NTSC";s:7:"License";s:4:"Home";}

或者

a:1:{s:4:"Size";s:1:"S";}

我需要直接使用MySQL提取引号之间的内容,以显示:

Format: NTSC, License: Home

或者

Size: S

所以我需要基本保持引号之间的内容并将其连接起来。我可以使用像Looking to extract data between parentheses in a string via MYSQLMySQL: Use REGEX to extract string (select REGEX)这样的东西,但我不能,因为属性的数量是任意的(0,1,2,3,...),而不是总是2,例如。

有什么办法吗?

2 个答案:

答案 0 :(得分:1)

编写PHP脚本以反序列化并打印它。它比使用正则表达式更容易。

答案 1 :(得分:1)

在PHP中反序列化:最好的选择就是反序列化它,连接它并将它交给你的客户端(为了提高性能,你可以在将它们带到PHP之前缩小行数。)

<?php
$data='a:2:{s:6:"Format";s:4:"NTSC";s:7:"License";s:4:"Home";}';

/* To unserialize and print */
$arr=unserialize($data); $out="";
foreach ($arr as $k => $val) {
    $out.=$k.":".$val." ";
}
print "$out<br>";
?>

PHP中的模式匹配:下一个选项是在PHP中使用正则表达式进行匹配(虽然这样做没有多大好处。反序列化更好)。我将在这里留下这个例子,以防你想用正则表达式匹配做什么。

<?php

$data='a:2:{s:6:"Format";s:4:"NTSC";s:7:"License";s:4:"Home";}';
preg_match_all('/"(.*?)"/',$data, $result);

$out="";
for ($i = 0; $i < count($result[0]); $i+=2) {
    print $result[1][$i].":".$result[1][$i+1]." ";
}
print "$out<br>";
?>

导出,处理,导入:如果不再以序列化格式写入表列,并且只读取它(以获取旧数据),则可以将其导出作为csv文件,在perl中处理数据,添加一个新列以包含&#34; Tag = Value&#34;格式由空格分隔,并使用插入新数据的新列将文件导回数据库。如果需要,我可以为您提供perl脚本来解析/转换序列化数据。

使用UDF在MySql中进行模式匹配:另一方面,如果您只想在MySql查询中使用正则表达式(以提取标记/值),您可以通过使用这extension。它需要从已安装的源构建。

回答有关RLIKE的问题:如果你知道序列化数据的所有可能格式(如果它看起来很简单),你可以在将行放入PHP之前运行正则表达式匹配(如果性能很重要)。

create table tt (data varchar(100));
insert into tt values ("a:2:{s:6:\"Format\";s:4:\"NTSC\";s:7:\"License\";s:4:\"Home\";}");

select data from tt where data rlike '"Format";s:[0-9]+:"NTSC"';