【问题标题】:How to capture/isolate a specific substring in text with repeated formatting?如何以重复格式捕获/隔离文本中的特定子字符串?
【发布时间】:2012-05-25 13:31:03
【问题描述】:

我正在学习正则表达式,但我不确定如何从输出中“取出”特定内容。

示例 - 我想检索特定 CSS 样式的值。

这是一个简化的例子:

$source = 'foo { bar: Something }
           foo { bar: Else }
           foo { bar: Yay }';

我想在 var_dump 之后输出这个:

array(3) {
  [0]=>
  string(9) "Something"
  [1]=>
  string(4) "Else"
  [2]=>
  string(3) "Yay"
}

这是我的正则表达式:

preg_match_all("/foo\s*{\s*bar:\s*[A-Za-z]*\s*}/",$source,$matches);
    
foreach($matches as $example) {
   echo '<pre>';
   var_dump($example);
   echo '</pre>';
   }

我得到:

array(3) {
  [0]=>
  string(22) "foo { bar: Something }"
  [1]=>
  string(17) "foo { bar: Else }"
  [2]=>
  string(16) "foo { bar: Yay }"
}

如何限制我的输出数据,使其仅显示所需的内容,而不是与正则表达式匹配的所有内容?

【问题讨论】:

    标签: php regex preg-match-all capture-group


    【解决方案1】:
    preg_match_all("/foo\s*{\s*bar:\s*([A-Za-z]*)\s*}/",$source,$matches);
                                      ^----     ^----
    

    这种情况下的括号称为“捕获组”

    http://nz.php.net/manual/en/regexp.reference.subpatterns.php

    【讨论】:

      【解决方案2】:

      在要匹配的区域周围使用括号。

      【讨论】:

        【解决方案3】:

        尝试将您的正则表达式更改为

        /foo\s*{\s*bar:\s*([A-Za-z]*)\s*}/
        

        然后再次查看输出。然后,您可能会在输出中看到仅包含您要获取的文本的条目。

        通过使用(),您可以在正则表达式中创建一个组,preg_match_all 函数也将只输出这些组内的内容。

        输出数组

        一个例子:

        $text = 'Here comes a number: 5, here comes a number: 3
                  and here comes a number: 4';
        preg_match_all( '/[Hh]ere comes a number: ([0-9])/', $text, $matches );
        

        运行此代码后,$matches 现在将是:

        array(
            array( 'Here comes a number: 5', '5' ),
            array( 'Here comes a number: 5', '5' ),
            array( 'Here comes a number: 5', '5' )
        )
        

        如您所见,$matches 将为每个匹配的字符串包含一个数组。第一个条目 ($matches[0]) 将始终包含完整匹配的字符串。其他索引($matches[1]$matches[2] 等)将仅按顺序包含指定组的值。如果您指定一个可选组(例如test([0-9])?),则关联的索引将包含一个null 值。

        从输出中排除组

        有时您想指定一个组,但不想将其包含在输出数组中。例如:

        $text = 'Here comes a number: 5, here comes another number: 3
                  and here comes a number: 4';
        preg_match_all( '/[Hh]ere comes a(nother)? number: ([0-9])/', $text, $matches );
        

        我为nother 添加了一个组,因为我希望它是可选的。现在我的$matches[1] 包含"nother"null,我的$matches[2] 包含实际数字。由于我对用户是选择写 "another" 还是 "a" 不感兴趣,所以我想从输出中排除这个组。

        这可以通过以(?: 开头的组来完成。结果代码:

        $text = 'Here comes a number: 5, here comes a number: 3
                   and here comes a number: 4';
        preg_match_all( '/[Hh]ere comes a(?:nother)? number: ([0-9])/', $text, $matches );
        

        (?:nother) 组在输出中被忽略,$matches[1] 引用我们感兴趣的实际数字。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-11-27
          • 1970-01-01
          • 2014-12-04
          • 1970-01-01
          • 1970-01-01
          • 2021-02-15
          • 2018-08-02
          • 2016-08-04
          相关资源
          最近更新 更多