我有这个网址:
uploads/offers/picture/_YToxOntzOjc6Im9wdGlvbnMiO3M6MTY6Inpvb21Dcm9wLDI4MS_/_wyMDAiO30=_/518edc82d94b0-201341717250_descuen_a06d000000fkvwpiak_1_1.jpg
我需要获取所有/_(.*)_/
个部分,但我的preg_match_all
表达式看起来很糟糕:
preg_match_all('#/_([^_/]+)_/#', $url, $params);
返回
Array
(
[0] => Array
(
[0] => /_YToxOntzOjc6Im9wdGlvbnMiO3M6MTY6Inpvb21Dcm9wLDI4MS_/
)
[1] => Array
(
[0] => YToxOntzOjc6Im9wdGlvbnMiO3M6MTY6Inpvb21Dcm9wLDI4MS
)
)
我需要
Array
(
[0] => Array
(
[0] => /_YToxOntzOjc6Im9wdGlvbnMiO3M6MTY6Inpvb21Dcm9wLDI4MS_/
[1] => /_wyMDAiO30=_/
)
[1] => Array
(
[0] => YToxOntzOjc6Im9wdGlvbnMiO3M6MTY6Inpvb21Dcm9wLDI4MS
[1] => wyMDAiO30=
)
)
表达式中常见字符串部分的一些问题?
答案 0 :(得分:2)
正则表达式中的最终/
最终消耗它。解决这个问题的一个简单方法是使用前瞻。
preg_match_all('#/_([^_/]+)_(?=/)#', $url, $params);
答案 1 :(得分:2)
中间的/
不匹配两次,但是,你可以使用lookahead / behind断言:
preg_match_all('#(?<=/_)[^_/]+(?=_/)#', $url,$params);
array(1) {
[0]=>
array(2) {
[0]=>
string(50) "YToxOntzOjc6Im9wdGlvbnMiO3M6MTY6Inpvb21Dcm9wLDI4MS"
[1]=>
string(10) "wyMDAiO30="
}
}
答案 2 :(得分:2)
您当前解决方案的一个问题是,它与表达式末尾的/
匹配,Explosion Pill's answer表示;使用积极的前瞻将解决这个问题。
另一个可能的问题是,如果输入包含下划线作为您想要捕获的匹配项的一部分,[^_/]
部分最终可能会破坏正则表达式。
一次解决这两个问题:
~/_(.+?)_(?=/)~
在我看来,这与你所追求的更接近:“只要你看到序列/_
开始捕获所有输入,直到你遇到序列_/
”。输入中的单独下划线不会破坏这一点。
答案 3 :(得分:0)
您的表达式会选择两个_
,因此会跳过wyMDAiO30=
部分。
我建议您使用explode("_", $url)
(或preg_split(...)
如果以上只是一个示例,您需要正则表达式来识别拆分字符/子字符串。)
如果您真的坚持使用preg_match_all
,请查看文档。有一种方法可以说“匹配这个,但不要在字符串中包含它”。我认为它类似于#_([^_/]+)(?=_)#
。
答案 4 :(得分:0)
最佳解决方案可能是首先拆分字符串,然后检查下划线:
<?php
$data = explode('/', $url);
foreach($data as $val) {
if(substr($val, 0, 1) === '_' && substr($val, -1) === '_') {
// ok
}
}