【问题标题】:Get all matches in a regular expression获取正则表达式中的所有匹配项
【发布时间】:2013-05-09 03:44:41
【问题描述】:

我有这个网址:

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

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

【问题讨论】:

    标签: php regex preg-match-all


    【解决方案1】:

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

    <?php
    
    $data = explode('/', $url);
    
    foreach($data as $val) {
        if(substr($val, 0, 1) === '_' && substr($val, -1) === '_') {
            // ok
        }
    }
    

    【讨论】:

      【解决方案2】:

      您当前解决方案的一个问题是它与Explosion Pill's answer 所说的表达式末尾的/ 匹配;使用积极的前瞻将解决这个问题。

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

      同时解决这两个问题:

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

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

      【讨论】:

        【解决方案3】:

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

        preg_match_all('#(?<=/_)[^_/]+(?=_/)#', $url,$params);
        
        array(1) {
          [0]=>
          array(2) {
            [0]=>
            string(50) "YToxOntzOjc6Im9wdGlvbnMiO3M6MTY6Inpvb21Dcm9wLDI4MS"
            [1]=>
            string(10) "wyMDAiO30="
          }
        }
        

        【讨论】:

          【解决方案4】:

          您的表达式选择了两个_,因此wyMDAiO30= 部分被跳过。

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

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

          【讨论】:

          • 问题出在/,而不是_
          • 对不起,买我不能被_爆,因为URL可以有一些_不需要,表达式必须是/_.*_/
          【解决方案5】:

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

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

          【讨论】:

          • 向前看那个巨大的未知数.. 谢谢!
          猜你喜欢
          • 1970-01-01
          • 2010-10-13
          • 1970-01-01
          • 2010-11-16
          • 2010-10-12
          • 1970-01-01
          • 1970-01-01
          • 2016-11-04
          • 1970-01-01
          相关资源
          最近更新 更多