2

我有这个网址:

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=
        )
)

表达式中常见的字符串部分有问题吗?

4

5 回答 5

2

中间/不匹配两次,但是,您可以使用前瞻/后置断言:

preg_match_all('#(?<=/_)[^_/]+(?=_/)#', $url,$params);

array(1) {
  [0]=>
  array(2) {
    [0]=>
    string(50) "YToxOntzOjc6Im9wdGlvbnMiO3M6MTY6Inpvb21Dcm9wLDI4MS"
    [1]=>
    string(10) "wyMDAiO30="
  }
}
于 2013-05-14T18:39:31.970 回答
2

您当前解决方案的一个问题是它与/表达式末尾的Explosion Pill 的答案相匹配;使用积极的前瞻将解决该问题。

另一个可能的问题是,[^_/]如果输入包含下划线作为您想要捕获的匹配项的一部分,则该部分最终可能会破坏正则表达式。

要同时解决这两个问题:

~/_(.+?)_(?=/)~

在我看来,这似乎更接近你所追求的:“每当你看到序列/_开始捕获所有输入,直到你遇到序列_/”。输入中的单独下划线不会破坏这一点。

于 2013-05-14T18:40:28.580 回答
2

正则表达式中的 final 最终/消耗了它。解决此问题的一种简单方法是使用前瞻。

preg_match_all('#/_([^_/]+)_(?=/)#', $url, $params);
于 2013-05-14T18:36:03.210 回答
0

您的表情选择了 TWO _,因此wyMDAiO30=跳过了该部分。

我建议您使用explode("_", $url)(或者preg_split(...)如果以上只是一个示例并且您需要正则表达式来识别拆分字符/子字符串)。

如果您真的坚持使用preg_match_all,请查看文档。有一种方法可以说“匹配这个,但不要将它包含在字符串中”。我认为这有点像#_([^_/]+)(?=_)#

于 2013-05-14T18:39:10.700 回答
0

最好的解决方案可能是先拆分字符串,然后检查下划线:

<?php

$data = explode('/', $url);

foreach($data as $val) {
    if(substr($val, 0, 1) === '_' && substr($val, -1) === '_') {
        // ok
    }
}
于 2013-05-14T18:54:34.057 回答