MbRegex::getAll()   B
last analyzed

Complexity

Conditions 5
Paths 2

Size

Total Lines 28
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 28
ccs 16
cts 16
cp 1
rs 8.439
c 0
b 0
f 0
cc 5
eloc 16
nc 2
nop 3
crap 5
1
<?php
2
3
namespace Gobie\Regex\Wrappers\Mb;
4
5
/**
6
 * Wrapper around mbstring extension.
7
 *
8
 * Usage:
9
 * <code>
10
 * if ($matches = MbRegex::getAll($pattern, $subject)) {
11
 *   // do stuff here with $matches
12
 * }
13
 * </code>
14
 *
15
 * @link http://php.net/book.mbstring.php
16
 */
17
class MbRegex
18
{
19
20
    /**
21
     * Regular expression match and return if pattern matches given subject.
22
     *
23
     * @param string $pattern Pattern
24
     * @param string $subject Subject
25
     * @param string $option  Option
26
     * @return bool True if pattern matches given subject, false otherwise
27
     * @throws MbRegexException When compilation error occurs
28
     * @link http://php.net/function.mb-ereg-search.php
29
     */
30 5
    public static function match($pattern, $subject, $option = '')
0 ignored issues
show
Coding Style introduced by
function match() does not seem to conform to the naming convention (^(?:is|has|should|may|supports)).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
31
    {
32 5
        static::setUp($pattern);
33 5
        \mb_ereg_search_init($subject, $pattern, $option);
34 4
        $res = \mb_ereg_search();
35 4
        static::tearDown();
36
37 4
        return (bool) $res;
38
    }
39
40
    /**
41
     * Regular expression match and return first match.
42
     *
43
     * @param string $pattern Pattern
44
     * @param string $subject Subject
45
     * @param string $option  Option
46
     * @return string[] Array with first match that matches given subject, empty array otherwise
47
     * @throws MbRegexException When compilation error occurs
48
     * @link http://php.net/function.mb-ereg-search-regs.php
49
     */
50 5
    public static function get($pattern, $subject, $option = '')
51
    {
52 5
        static::setUp($pattern);
53 5
        \mb_ereg_search_init($subject, $pattern, $option);
54 4
        $matches = \mb_ereg_search_regs();
55 4
        static::tearDown();
56
57 4
        return $matches ? : array();
58
    }
59
60
    /**
61
     * Global regular expression match and return all matches.
62
     *
63
     * @param string $pattern Pattern
64
     * @param string $subject Subject
65
     * @param string $option  Option
66
     * @return string[][] Array of matches that match given subject, empty array otherwise
67
     * @throws MbRegexException When compilation error occurs
68
     * @link http://php.net/function.mb-ereg-search-regs.php
69
     */
70 6
    public static function getAll($pattern, $subject, $option = '')
71
    {
72 6
        static::setUp($pattern);
73
74 6
        $position   = 0;
75 6
        $subjectLen = \mb_strlen($subject);
76 6
        $matches    = array();
77
78 6
        \mb_ereg_search_init($subject, $pattern, $option);
79 5
        while ($position !== false && $position < $subjectLen) {
80 5
            \mb_ereg_search_setpos($position);
81
82 5
            $result = \mb_ereg_search_regs();
83 5
            if ($result === false) {
84 3
                break;
85
            }
86
87 4
            foreach ($result as $key => $part) {
88 4
                $matches[$key][] = $part;
89
            }
90
91 4
            $position = \mb_ereg_search_getpos();
92
        }
93
94 5
        static::tearDown();
95
96 5
        return $matches;
97
    }
98
99
    /**
100
     * Regular expression replace and return replaced.
101
     *
102
     * Warning, take care that callback does not trigger any errors or the PHP will just die with some weird exit code.
103
     *
104
     * @param string|string[]         $pattern     Pattern or array of patterns
105
     * @param callable|string|mixed[] $replacement Replacement (string or callback) or array of replacements
106
     * @param string|string[]         $subject     Subject or array of subjects
107
     * @param string                  $option      Option
108
     * @return string|string[] Replaced subject or array of subjects
109
     * @throws MbRegexException When compilation error occurs
110
     * @link http://php.net/function.mb-ereg-replace.php
111
     * @link http://php.net/function.mb-ereg-replace-callback.php
112
     */
113 18 View Code Duplication
    public static function replace($pattern, $replacement, $subject, $option = '')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
114
    {
115 18
        static::setUp($pattern);
116
117 18
        $replaceMap = self::prepareReplaceMap($pattern, $replacement);
118
119 17
        $result = array();
120 17
        foreach ((array) $subject as $key => $subjectPart) {
121 17
            foreach ($replaceMap as $item) {
122 16
                list($pattern, $replacement) = $item;
123
124 16
                $subjectPart = self::execReplace($pattern, $replacement, $subjectPart, $option);
125
            }
126 14
            $result[$key] = $subjectPart;
127
        }
128
129 14
        static::tearDown();
130
131 14
        return (\is_array($subject) ? $result : \reset($result)) ? : $subject;
132
    }
133
134
    /**
135
     * Regular expression split and return all parts.
136
     *
137
     * @param string $pattern Pattern
138
     * @param string $subject Subject
139
     * @param int    $limit   Limit
140
     * @param string $option  Option
141
     * @return string[] Array of split parts, array with original string otherwise
142
     * @throws MbRegexException When compilation error occurs
143
     * @link http://php.net/function.mb-split.php
144
     */
145 6
    public static function split($pattern, $subject, $option = '', $limit = -1)
146
    {
147 6
        static::setUp($pattern);
148
149 6
        $position     = 0;
150 6
        $lastPosition = 0;
151 6
        $res          = array();
152 6
        $subjectLen   = \mb_strlen($subject);
153
154
        do {
155 6
            \mb_ereg_search_init($subject, $pattern, $option);
156 5
            \mb_ereg_search_setpos($position);
157
158 5
            $matches = \mb_ereg_search_regs();
159 5
            if ($matches === false) {
160 3
                break;
161
            }
162
163 4
            $position     = \mb_ereg_search_getpos();
164 4
            $res[]        = \mb_substr($subject, $lastPosition, $position - \mb_strlen($matches[0]) - $lastPosition);
165 4
            $lastPosition = $position;
166 4
        } while ($position < $subjectLen && --$limit !== 1);
167
168 5
        if ($lastPosition <= $subjectLen) {
169 5
            $res[] = \mb_substr($subject, $lastPosition);
170
        }
171
172 5
        static::tearDown();
173
174 5
        return $res;
175
    }
176
177
    /**
178
     * Regular expression grep and return matching items.
179
     *
180
     * @param string          $pattern Pattern
181
     * @param string|string[] $subject Subject or array of subjects
182
     * @param string          $option  Option
183
     * @return string[] Array with items that matches given pattern, empty array otherwise
184
     * @throws MbRegexException When compilation error occurs
185
     * @link http://php.net/function.mb-ereg-search.php
186
     */
187 5
    public static function grep($pattern, $subject, $option = '')
188
    {
189 5
        static::setUp($pattern);
190
191 5
        $matches = array();
192 5
        foreach ((array) $subject as $key => $subjectPart) {
193 5
            \mb_ereg_search_init($subjectPart, $pattern, $option);
194 4
            if (\mb_ereg_search()) {
195 4
                $matches[$key] = $subjectPart;
196
            }
197
        }
198
199 4
        static::tearDown();
200
201 4
        return $matches;
202
    }
203
204
    /**
205
     * Regular expression filter and return only replaced.
206
     *
207
     * Warning, take care that callback does not trigger any errors or the PHP will just die with some weird exit code.
208
     *
209
     * @param string|string[]         $pattern     Pattern or array of patterns
210
     * @param callable|string|mixed[] $replacement Replacement (string or callback) or array of replacements
211
     * @param string|string[]         $subject     Subject or array of subjects
212
     * @param string                  $option      Option
213
     * @return string[] Array of filtered subjects
214
     * @throws MbRegexException When compilation error occurs
215
     * @link http://php.net/function.mb-ereg-search.php
216
     * @link http://php.net/function.mb-ereg-replace.php
217
     * @link http://php.net/function.mb-ereg-replace-callback.php
218
     */
219 15 View Code Duplication
    public static function filter($pattern, $replacement, $subject, $option = '')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
220
    {
221 15
        static::setUp($pattern);
222
223 15
        $replaceMap = self::prepareReplaceMap($pattern, $replacement);
224
225 14
        $result = array();
226 14
        foreach ((array) $subject as $key => $subjectPart) {
227 14
            foreach ($replaceMap as $item) {
228 13
                list($pattern, $replacement) = $item;
229
230 13
                \mb_ereg_search_init($subjectPart, $pattern, $option);
231 11
                if (!\mb_ereg_search()) {
232 9
                    continue;
233
                }
234
235 9
                $subjectPart  = self::execReplace($pattern, $replacement, $subjectPart, $option);
236 11
                $result[$key] = $subjectPart;
237
            }
238
        }
239
240 11
        static::tearDown();
241
242 11
        return $result;
243
    }
244
245
    /**
246
     * Prepare error handler for catching compilation errors.
247
     *
248
     * @param string|string[] $pattern Pattern or array of patterns
249
     */
250
    protected static function setUp($pattern)
251
    {
252 60
        \set_error_handler(function ($errno, $errstr) use ($pattern) {
253 13
            \restore_error_handler();
254 13
            throw new MbRegexException($errstr, null, $pattern);
255 60
        });
256 60
    }
257
258
    /**
259
     * Clean up after setUp().
260
     */
261 47
    protected static function tearDown()
262
    {
263 47
        \restore_error_handler();
264 47
    }
265
266
    /**
267
     * Prepare map (pattern, replacement) from arguments.
268
     *
269
     * @param string|string[]         $pattern     Pattern or array of patterns
270
     * @param callable|string|mixed[] $replacement Replacement (string or callback) or array of replacements
271
     * @return string[][] Array of pattern and replacement
272
     */
273 33
    private static function prepareReplaceMap($pattern, $replacement)
274
    {
275 33
        $isPatternArray     = \is_array($pattern);
276 33
        $isReplacementArray = \is_array($replacement) && !\is_callable($replacement);
277
278 33
        if (!$isPatternArray && $isReplacementArray) {
279 2
            \trigger_error('Parameter mismatch, pattern is a string while replacement is an array', \E_USER_WARNING);
280
        }
281
282 31
        if ($isPatternArray) {
283 15
            $replacement = $isReplacementArray
284 9
                ? \array_pad($replacement, \count($pattern), '')
285 15
                : \array_fill(0, \count($pattern), $replacement);
286
        } else {
287 16
            $pattern     = (array) $pattern;
288 16
            $replacement = (array) $replacement;
289
        }
290
291 31
        return \array_map(null, $pattern, $replacement);
292
    }
293
294
    /**
295
     * Replace subject by callback or by string.
296
     *
297
     * @param string          $pattern     Pattern
298
     * @param callable|string $replacement Replacement
299
     * @param string          $subject     Subject
300
     * @param string          $option      Option
301
     * @return string Replaced subject
302
     */
303 25
    private static function execReplace($pattern, $replacement, $subject, $option)
304
    {
305 25
        return (\is_object($replacement) || \is_array($replacement)) && \is_callable($replacement)
306 6
            ? \mb_ereg_replace_callback($pattern, $replacement, $subject, $option)
307 24
            : \mb_ereg_replace($pattern, $replacement, $subject, $option);
308
    }
309
}
310