summaryrefslogtreecommitdiff
path: root/ext/spl/internal/regexiterator.inc
blob: 706eff33a7159e360e0872d38935c5d251a5bed8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
<?php

/** @file regexiterator.inc
 * @ingroup SPL
 * @brief class RegexIterator
 * @author  Marcus Boerger
 * @date    2003 - 2009
 *
 * SPL - Standard PHP Library
 */

/**
 * @brief   Regular expression filter for iterators
 * @author  Marcus Boerger
 * @version 1.0
 * @since PHP 5.1
 *
 * This filter iterator assumes that the inner iterator
 */
class RegexIterator extends FilterIterator
{
	const USE_KEY     = 0x00000001; /**< If present in $flags the key is
	                                     used rather then the current value. */

	const MATCH       = 0; /**< Mode: Executed a plain match only      */
	const GET_MATCH   = 1; /**< Mode: Return the first matche (if any) */
	const ALL_MATCHES = 2; /**< Mode: Return all matches (if any)      */
	const SPLIT       = 3; /**< Mode: Return the split values (if any) */
	const REPLACE     = 4; /**< Mode: Replace the input key or current */

	private $regex;     /**< the regular expression to match against */
	private $mode;      /**< operation mode (one of self::MATCH,
	                         self::GET_MATCH, self::ALL_MATCHES, self::SPLIT) */
	private $flags;     /**< special flags (self::USE_KEY) */
	private $preg_flags;/**< PREG_* flags, see preg_match(), preg_match_all(),
	                         preg_split() */
	private $key;       /**< the value used for key() */
	private $current;   /**< the value used for current() */

	/**
	 * Constructs a regular expression filter around an iterator whose
	 * elemnts or keys are strings.
	 *
	 * @param it          inner iterator
	 * @param regex       the regular expression to match
	 * @param mode        operation mode (one of self::MATCH, self::GET_MATCH,
	 *                    self::ALL_MATCHES, self::SPLIT)
	 * @param flags       special flags (self::USE_KEY)
	 * @param preg_flags  global PREG_* flags, see preg_match(),
	 *                    preg_match_all(), preg_split()
	 */
	function __construct(Iterator $it, $regex, $mode = 0, $flags = 0, $preg_flags = 0) {
		parent::__construct($it);
		$this->regex = $regex;
		$this->flags = $flags;
		$this->mode = $mode;
		$this->preg_flags = $preg_flags;
	}

	/**
	 * Match current or key against regular expression using mode, flags and
	 * preg_flags.
	 *
	 * @return whether this is a match
	 *
	 * @warning never call this twice for the same state
	 */
	function accept()
	{
		$matches       = array();
		$this->key     = parent::key();
		$this->current = parent::current();
		/* note that we use $this->current, rather than calling parent::current() */
		$subject = ($this->flags & self::USE_KEY) ? $this->key : $this->current;
		switch($this->mode)
		{
			case self::MATCH:
				return preg_match($this->regex, $subject, $matches, $this->preg_flags);

			case self::GET_MATCH:
				$this->current = array();
				return preg_match($this->regex, $subject, $this->current, $this->preg_flags) > 0;

			case self::ALL_MATCHES:
				$this->current = array();
				return preg_match_all($this->regex, $subject, $this->current, $this->preg_flags) > 0;

			case self::SPLIT:
				$this->current = array();
				preg_split($this->regex, $subject, $this->current, $this->preg_flags) > 1;

			case self::REPLACE:
				$this->current = array();
				$result = preg_replace($this->regex, $this->replacement, $subject);
				if ($this->flags & self::USE_KEY)
				{
					$this->key = $result;
				}
				else
				{
					$this->current = $result;
				}
		}
	}

	/** @return the key after accept has been called
	 */
	function key()
	{
		return $this->key;
	}

	/** @return the current value after accept has been called
	 */
	function current()
	{
		return $this->current;
	}

	/** @return current operation mode
	 */
	function getMode()
	{
		return $this->mode;
	}

	/** @param mode new operaion mode
	 */
	function setMode($mode)
	{
		$this->mode = $mode;
	}

	/** @return current operation flags
	 */
	function getFlags()
	{
		return $this->flags;
	}

	/** @param flags new operaion flags
	 */
	function setFlags($flags)
	{
		$this->flags = $flags;
	}

	/** @return current PREG flags
	 */
	function getPregFlags()
	{
		return $this->preg_flags;
	}

	/** @param preg_flags new PREG flags
	 */
	function setPregFlags($preg_flags)
	{
		$this->preg_flags = $preg_flags;
	}

	/** @return current regular expression
	*/
	function getRegex()
	{
		return $this->regex;
	}
}

?>