1<?php 2/* 3 * $Id: 94607411e16d4c9091369ff4a65ea8f44bde8781 $ 4 * 5 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 6 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 7 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 8 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 9 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 10 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 11 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 12 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 13 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 14 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 15 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 16 * 17 * This software consists of voluntary contributions made by many individuals 18 * and is licensed under the LGPL. For more information please see 19 * <http://phing.info>. 20 */ 21 22require_once 'phing/util/regexp/RegexpEngine.php'; 23 24/** 25 * PREG Regexp Engine. 26 * Implements a regexp engine using PHP's preg_match(), preg_match_all(), and preg_replace() functions. 27 * 28 * @author hans lellelid, hans@velum.net 29 * @package phing.util.regexp 30 */ 31class PregEngine implements RegexpEngine { 32 33 /** 34 * Set to null by default to distinguish between false and not set 35 * @var boolean 36 */ 37 private $ignoreCase = null; 38 39 /** 40 * Set to null by default to distinguish between false and not set 41 * @var boolean 42 */ 43 private $multiline = null; 44 45 /** 46 * Pattern modifiers 47 * @link http://php.net/manual/en/reference.pcre.pattern.modifiers.php 48 * @var string 49 */ 50 private $modifiers = null; 51 52 /** 53 * Sets pattern modifiers for regex engine 54 * 55 * @param string $mods Modifiers to be applied to a given regex 56 * @return void 57 */ 58 public function setModifiers($mods) { 59 $this->modifiers = (string)$mods; 60 } 61 62 /** 63 * Gets pattern modifiers. 64 * @return string 65 */ 66 public function getModifiers() { 67 $mods = $this->modifiers; 68 if($this->getIgnoreCase()) { 69 $mods .= 'i'; 70 } elseif($this->getIgnoreCase() === false) { 71 $mods = str_replace('i', '', $mods); 72 } 73 if($this->getMultiline()) { 74 $mods .= 's'; 75 } elseif($this->getMultiline() === false) { 76 $mods = str_replace('s', '', $mods); 77 } 78 // filter out duplicates 79 $mods = preg_split('//', $mods, -1, PREG_SPLIT_NO_EMPTY); 80 $mods = implode('', array_unique($mods)); 81 return $mods; 82 } 83 84 /** 85 * Sets whether or not regex operation is case sensitive. 86 * @param boolean $bit 87 * @return void 88 */ 89 function setIgnoreCase($bit) { 90 $this->ignoreCase = (boolean) $bit; 91 } 92 93 /** 94 * Gets whether or not regex operation is case sensitive. 95 * @return boolean 96 */ 97 function getIgnoreCase() { 98 return $this->ignoreCase; 99 } 100 101 /** 102 * Sets whether regexp should be applied in multiline mode. 103 * @param boolean $bit 104 */ 105 function setMultiline($bit) { 106 $this->multiline = $bit; 107 } 108 109 /** 110 * Gets whether regexp is to be applied in multiline mode. 111 * @return boolean 112 */ 113 function getMultiline() { 114 return $this->multiline; 115 } 116 117 /** 118 * The pattern needs to be converted into PREG style -- which includes adding expression delims & any flags, etc. 119 * @param string $pattern 120 * @return string prepared pattern. 121 */ 122 private function preparePattern($pattern) 123 { 124 // Use backquotes since hardly ever found in a regexp pattern, avoids using preg_quote 125 return '`'.$pattern.'`' . $this->getModifiers(); 126 } 127 128 /** 129 * Matches pattern against source string and sets the matches array. 130 * @param string $pattern The regex pattern to match. 131 * @param string $source The source string. 132 * @param array $matches The array in which to store matches. 133 * @return boolean Success of matching operation. 134 */ 135 function match($pattern, $source, &$matches) { 136 return preg_match($this->preparePattern($pattern), $source, $matches); 137 } 138 139 /** 140 * Matches all patterns in source string and sets the matches array. 141 * @param string $pattern The regex pattern to match. 142 * @param string $source The source string. 143 * @param array $matches The array in which to store matches. 144 * @return boolean Success of matching operation. 145 */ 146 function matchAll($pattern, $source, &$matches) { 147 return preg_match_all($this->preparePattern($pattern), $source, $matches); 148 } 149 150 /** 151 * Replaces $pattern with $replace in $source string. 152 * References to \1 group matches will be replaced with more preg-friendly 153 * $1. 154 * @param string $pattern The regex pattern to match. 155 * @param string $replace The string with which to replace matches. 156 * @param string $source The source string. 157 * @return string The replaced source string. 158 */ 159 function replace($pattern, $replace, $source) { 160 // convert \1 -> $1, because we want to use the more generic \1 in the XML 161 // but PREG prefers $1 syntax. 162 $replace = preg_replace('/\\\(\d+)/', '\$$1', $replace); 163 return preg_replace($this->preparePattern($pattern), $replace, $source); 164 } 165 166} 167 168