从字符串中获取特殊值(正则表达式)

时间:2015-06-15 17:15:01

标签: php regex

使用正则表达式对我来说很难。

我正在尝试从此字符串中获取“strong” 149 150

a:1:{s:7:"sliders";a:1:{s:10:"fullscreen";a:5:{s:6:"slides";a:2:{i:47;a:4:{s:9:"attach_id";s:3:"149";s:10:"slide_type";s:5:"image";s:5:"title";a:2:{s:5:"value";s:0:"";s:5:"color";s:0:"";}s:7:"caption";a:2:{s:5:"value";s:0:"";s:5:"color";s:0:"";}}i:48;a:4:{s:9:"attach_id";s:3:"150";s:10:"slide_type";s:5:"image";s:5:"title";a:2:{s:5:"value";s:0:"";s:5:"color";s:0:"";}s:7:"caption";a:2:{s:5:"value";s:0:"";s:5:"color";s:0:"";}}}s:9:"fit_style";s:7:"default";s:8:"controls";s:7:"default";s:6:"thumbs";s:3:"yes";s:8:"autoplay";s:7:"default";}}}

我尝试了这个没有任何好结果:

/^.*_id";s:3:"(.*)";.*$/

5 个答案:

答案 0 :(得分:2)

这是一个序列化的字符串,使用unserialize

参考:http://php.net/manual/en/function.unserialize.php

答案 1 :(得分:2)

如果你坚持使用正则表达式,你需要在量词中添加一个'?`,这样就不会匹配你组中的整个字符串了:

/^.*_id";s:3:"(.*?)";.*$/

但是,这只会映射一个值。要映射所有这些,请使用:

_id";s:3:"(.*?)";

答案 2 :(得分:1)

您应该使用解析器。使用正则表达式,您只需执行

(?<=;s:3:")\d+

参见演示。

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

$re = "/(?<=;s:3:\")\\d+/"; 
$str = "a:1:{s:7:\"sliders\";a:1:{s:10:\"fullscreen\";a:5:{s:6:\"slides\";a:2:{i:47;a:4:{s:9:\"attach_id\";s:3:\"149\";s:10:\"slide_type\";s:5:\"image\";s:5:\"title\";a:2:{s:5:\"value\";s:0:\"\";s:5:\"color\";s:0:\"\";}s:7:\"caption\";a:2:{s:5:\"value\";s:0:\"\";s:5:\"color\";s:0:\"\";}}i:48;a:4:{s:9:\"attach_id\";s:3:\"150\";s:10:\"slide_type\";s:5:\"image\";s:5:\"title\";a:2:{s:5:\"value\";s:0:\"\";s:5:\"color\";s:0:\"\";}s:7:\"caption\";a:2:{s:5:\"value\";s:0:\"\";s:5:\"color\";s:0:\"\";}}}s:9:\"fit_style\";s:7:\"default\";s:8:\"controls\";s:7:\"default\";s:6:\"thumbs\";s:3:\"yes\";s:8:\"autoplay\";s:7:\"default\";}}}"; 

preg_match_all($re, $str, $matches);

答案 3 :(得分:1)

你可以这样做:

$arr = unserialize($input);
foreach ($arr['sliders']['fullscreen']['slides'] as $a) { echo $a['attach_id']. "\n"; }
149
150

答案 4 :(得分:1)

这是一个PHP序列化字符串,可以使用unserialize function in PHP进行解析。

但是,如果由于某种原因你真的需要使用RegEx:

您正在使用的RegEx匹配第一个值,然后字符串的整个剩余部分.*是贪婪的。相反,您希望它是懒惰的,因此您可以在*之后添加问号:/^.*_id";s:3:"(.*?)";.*$/

其次,因为您使用了锚^$,所以它只匹配一次。删除锚点,或复制模式:

/_id";s:3:"(.*?)";/

/^.*_id";s:3:"(.*?)";.*_id";s:3:"(.*?)";.*$/

您可以在此处了解有关Lazy vs Greedy的更多信息:http://www.regular-expressions.info/repeat.html

我的建议是使用定义的匹配而不是.*

/_id";s:3:"(\d*)";/

只要它是一个数字,这将使你的表达更具体,更清晰,供其他人阅读。

这是测试RegEx表达式的一个很好的操场:http://www.regexr.com/3b74b