MySQL提取SELECT中的几个子串,任意次数
MySQL extract several substrings in SELECT, an arbitrary number of times
所以我项目的前任编码员决定将 PHP 序列化信息放入 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 MYSQL or MySQL: Use REGEX to extract string (select REGEX) 的东西,但我不能,因为属性的数量是任意的(0,1,2,3,...)而不是总是 2 例如。
有什么办法吗?
写一个PHP脚本反序列化并打印出来。这比使用正则表达式更容易。
反序列化 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>";
?>
Export,Process,Import: 如果 table 列不再以序列化格式写入,并且仅被读取(返回遗留数据),您可以将其导出为 csv 文件,在 perl 中处理数据,添加一个新列以包含由空格分隔的 "Tag=Value" 格式,然后将文件导入回数据库中,其中包含一个新列新数据被插入。如果您需要它,我可以为您提供一个 perl 脚本来 parse/convert 序列化数据。
MySql 中使用 UDF 的模式匹配: 另一方面,如果您只想在 MySql 查询本身中使用正则表达式(以提取 tag/values),你可以使用这个 extension。它需要从源代码构建,安装。
回答有关 RLIKE 的问题:如果您知道序列化数据的所有可能格式(如果它对您来说看起来足够简单),您可以 运行 在将行放入 [=38] 之前进行正则表达式匹配=](如果性能很重要)。
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"';
所以我项目的前任编码员决定将 PHP 序列化信息放入 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 MYSQL or MySQL: Use REGEX to extract string (select REGEX) 的东西,但我不能,因为属性的数量是任意的(0,1,2,3,...)而不是总是 2 例如。
有什么办法吗?
写一个PHP脚本反序列化并打印出来。这比使用正则表达式更容易。
反序列化 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>";
?>
Export,Process,Import: 如果 table 列不再以序列化格式写入,并且仅被读取(返回遗留数据),您可以将其导出为 csv 文件,在 perl 中处理数据,添加一个新列以包含由空格分隔的 "Tag=Value" 格式,然后将文件导入回数据库中,其中包含一个新列新数据被插入。如果您需要它,我可以为您提供一个 perl 脚本来 parse/convert 序列化数据。
MySql 中使用 UDF 的模式匹配: 另一方面,如果您只想在 MySql 查询本身中使用正则表达式(以提取 tag/values),你可以使用这个 extension。它需要从源代码构建,安装。
回答有关 RLIKE 的问题:如果您知道序列化数据的所有可能格式(如果它对您来说看起来足够简单),您可以 运行 在将行放入 [=38] 之前进行正则表达式匹配=](如果性能很重要)。
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"';