Recipe 22.7. Preventing Parentheses from Capturing Text


22.7.1. Problem

You've used parentheses for grouping in a pattern, but you don't want the text that matches what's in the parentheses to show up in your array of captured matches.

22.7.2. Solution

Put ?: just after the opening parenthesis, as in Example 22-13.

Preventing text capture

<?php $html = '<link rel="icon" href="http://www.example.com/icon.gif"/> <link rel="prev" href="http://www.example.com/prev.xml"/> <link rel="next" href="http://www.example.com/next.xml"/>'; preg_match_all('/rel="(prev|next)" href="([^"]*?)"/', $html, $bothMatches); preg_match_all('/rel="(?:prev|next)" href="([^"]*?)"/', $html, $linkMatches); print '$bothMatches is: '; var_dump($bothMatches); print '$linkMatches is: '; var_dump($linkMatches); ?>

In Example 22-13, $bothMatches contains the values of the rel and the HRef attributes. $linkMatches, however, just contains the values of the href attributes. The code prints:

$bothMatches is: array(3) {   [0]=>   array(2) {     [0]=>     string(49) "rel="prev" href="http://www.example.com/prev.xml""     [1]=>     string(49) "rel="next" href="http://www.example.com/next.xml""   }   [1]=>   array(2) {     [0]=>     string(4) "prev"     [1]=>     string(4) "next"   }   [2]=>   array(2) {     [0]=>     string(31) "http://www.example.com/prev.xml"     [1]=>     string(31) "http://www.example.com/next.xml"   } } $linkMatches is: array(2) {   [0]=>   array(2) {     [0]=>     string(49) "rel="prev" href="http://www.example.com/prev.xml""     [1]=>     string(49) "rel="next" href="http://www.example.com/next.xml""   }   [1]=>   array(2) {     [0]=>     string(31) "http://www.example.com/prev.xml"     [1]=>     string(31) "http://www.example.com/next.xml"   } }

22.7.3. Discussion

Preventing capturing is particularly useful when a subpattern is optional. Since it might not show up in the array of captured text, an optional subpattern can change the number of pieces of captured text. This makes it hard to reference a particular matched piece of text at a given index. Making optional subpatterns non-capturing prevents this problem. Example 22-14 illustrates this distinction.

A non-capturing optional subpattern

 <?php $html = '<link rel="icon" href="http://www.example.com/icon.gif"/> <link rel="prev" title="Previous" href="http://www.example.com/prev.xml"/> <link rel="next" href="http://www.example.com/next.xml"/>'; preg_match_all('/rel="(?:prev|next)"(?: title="[^"]+?")? href= "([^"]*?)"/', $html, $linkMatches); print '$bothMatches is: '; var_dump($linkMatches); ?>

22.7.4. See Also

The PCRE Pattern Syntax documentation at http://php.net/reference.pcre.pattern.syntax.




PHP Cookbook, 2nd Edition
PHP Cookbook: Solutions and Examples for PHP Programmers
ISBN: 0596101015
EAN: 2147483647
Year: 2006
Pages: 445

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net