GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — develop ( a51068...9ecfaa )
by Baptiste
02:17
created

Str::getMatches()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 7
ccs 2
cts 2
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 6
nc 1
nop 3
crap 1
1
<?php
2
declare(strict_types = 1);
3
4
namespace Innmind\Immutable;
5
6
use Innmind\Immutable\Exception\RegexException;
7
use Innmind\Immutable\Exception\SubstringException;
8
9
class Str implements PrimitiveInterface, StringableInterface
10
{
11
    const PAD_RIGHT = STR_PAD_RIGHT;
12
    const PAD_LEFT = STR_PAD_LEFT;
13
    const PAD_BOTH = STR_PAD_BOTH;
14
    const PREG_NO_FLAGS = 0;
15
    const PREG_SPLIT_NO_EMPTY = PREG_SPLIT_NO_EMPTY;
16
    const PREG_SPLIT_DELIM_CAPTURE = PREG_SPLIT_DELIM_CAPTURE;
17
    const PREG_SPLIT_OFFSET_CAPTURE = PREG_SPLIT_OFFSET_CAPTURE;
18
    const PREG_OFFSET_CAPTURE = PREG_OFFSET_CAPTURE;
19
20
    private $value;
21
22 290
    public function __construct(string $value)
23
    {
24 290
        $this->value = $value;
25 290
    }
26
27
    /**
28
     * {@inheritdoc}
29
     */
30 2
    public function toPrimitive()
31
    {
32 2
        return $this->value;
33
    }
34
35
    /**
36
     * {@inheritdoc}
37
     */
38 184
    public function __toString(): string
39
    {
40 184
        return $this->value;
41
    }
42
43
    /**
44
     * Split the string into a collection of ones
45
     *
46
     * @param string $delimiter
47
     *
48
     * @return StreamInterface<self>
0 ignored issues
show
Documentation introduced by
The doc-type StreamInterface<self> could not be parsed: Expected "|" or "end of type", but got "<" at position 15. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
49
     */
50 4
    public function split(string $delimiter = null): StreamInterface
51
    {
52 4
        $parts = empty($delimiter) ?
53 4
                str_split($this->value) : explode($delimiter, $this->value);
54 4
        $stream = new Stream(self::class);
55
56 4
        foreach ($parts as $part) {
57 4
            $stream = $stream->add(new self($part));
1 ignored issue
show
Documentation introduced by
new self($part) is of type object<Innmind\Immutable\Str>, but the function expects a object<Innmind\Immutable\T>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
58
        }
59
60 4
        return $stream;
61
    }
62
63
    /**
64
     * Returns a collection of the string splitted by the given chunk size
65
     *
66
     * @param int $size
67
     *
68
     * @return StreamInterface<self>
0 ignored issues
show
Documentation introduced by
The doc-type StreamInterface<self> could not be parsed: Expected "|" or "end of type", but got "<" at position 15. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
69
     */
70 2
    public function chunk(int $size = 1): StreamInterface
71
    {
72 2
        $pieces = str_split($this->value, $size);
73 2
        $stream = new Stream(self::class);
74
75 2
        foreach ($pieces as $piece) {
76 2
            $stream = $stream->add(new self($piece));
1 ignored issue
show
Documentation introduced by
new self($piece) is of type object<Innmind\Immutable\Str>, but the function expects a object<Innmind\Immutable\T>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
77
        }
78
79 2
        return $stream;
80
    }
81
82
    /**
83
     * Returns the position of the first occurence of the string
84
     *
85
     * @param string $needle
86
     * @param int $offset
87
     *
88
     * @throws SubstringException If the string is not found
89
     *
90
     * @return int
91
     */
92 8
    public function position(string $needle, int $offset = 0): int
93
    {
94 8
        $position = mb_strpos($this->value, $needle, $offset);
95
96 8
        if ($position === false) {
97 4
            throw new SubstringException(sprintf(
98 4
                'Substring "%s" not found',
99
                $needle
100
            ));
101
        }
102
103 6
        return (int) $position;
104
    }
105
106
    /**
107
     * Replace all occurences of the search string with the replacement one
108
     *
109
     * @param string $search
110
     * @param string $replacement
111
     *
112
     * @return self
113
     */
114 2
    public function replace(string $search, string $replacement): self
115
    {
116 2
        return new self(str_replace(
117 2
            (string) $search,
118 2
            (string) $replacement,
119 2
            $this->value
120
        ));
121
    }
122
123
    /**
124
     * Returns the string following the given delimiter
125
     *
126
     * @param string $delimiter
127
     *
128
     * @throws SubstringException If the string is not found
129
     *
130
     * @return self
131
     */
132 4
    public function str(string $delimiter): self
133
    {
134 4
        $sub = mb_strstr($this->value, $delimiter);
135
136 4
        if ($sub === false) {
137 2
            throw new SubstringException(sprintf(
138 2
                'Substring "%s" not found',
139
                $delimiter
140
            ));
141
        }
142
143 2
        return new self($sub);
144
    }
145
146
    /**
147
     * Return the string in upper case
148
     *
149
     * @return self
150
     */
151 2
    public function toUpper(): self
152
    {
153 2
        return new self(mb_strtoupper($this->value));
154
    }
155
156
    /**
157
     * Return the string in lower case
158
     *
159
     * @return self
160
     */
161 2
    public function toLower(): self
162
    {
163 2
        return new self(mb_strtolower($this->value));
164
    }
165
166
    /**
167
     * Return the string length
168
     *
169
     * @return int
170
     */
171 4
    public function length(): int
172
    {
173 4
        return strlen($this->value);
174
    }
175
176
    /**
177
     * Reverse the string
178
     *
179
     * @return self
180
     */
181 2
    public function reverse(): self
182
    {
183 2
        return new self(strrev($this->value));
184
    }
185
186
    /**
187
     * Pad to the right
188
     *
189
     * @param int $length
190
     * @param string $character
191
     *
192
     * @return self
193
     */
194 2
    public function rightPad(int $length, string $character = ' '): self
195
    {
196 2
        return $this->pad($length, $character, self::PAD_RIGHT);
197
    }
198
199
    /**
200
     * Pad to the left
201
     *
202
     * @param int $length
203
     * @param string $character
204
     *
205
     * @return self
206
     */
207 2
    public function leftPad(int $length, string $character = ' '): self
208
    {
209 2
        return $this->pad($length, $character, self::PAD_LEFT);
210
    }
211
212
    /**
213
     * Pad both sides
214
     *
215
     * @param int $length
216
     * @param string $character
217
     *
218
     * @return self
219
     */
220 2
    public function uniPad(int $length, string $character = ' '): self
221
    {
222 2
        return $this->pad($length, $character, self::PAD_BOTH);
223
    }
224
225
    /**
226
     * Find length of initial segment not matching mask
227
     *
228
     * @param string $mask
229
     * @param int $start
230
     * @param int $length
231
     *
232
     * @return int
233
     */
234 2
    public function cspn(string $mask, int $start = 0, int $length = null): int
235
    {
236 2
        if ($length === null) {
237 2
            $value = strcspn($this->value, $mask, $start);
238
        } else {
239 2
            $value = strcspn(
240 2
                $this->value,
241
                $mask,
242
                $start,
243
                $length
244
            );
245
        }
246
247 2
        return (int) $value;
248
    }
249
250
    /**
251
     * Repeat the string n times
252
     *
253
     * @param int $repeat
254
     *
255
     * @return self
256
     */
257 2
    public function repeat(int $repeat): self
258
    {
259 2
        return new self(str_repeat($this->value, $repeat));
260
    }
261
262
    /**
263
     * Shuffle the string
264
     *
265
     * @return self
266
     */
267 2
    public function shuffle(): self
268
    {
269 2
        return new self(str_shuffle($this->value));
270
    }
271
272
    /**
273
     * Strip slashes
274
     *
275
     * @return self
276
     */
277 2
    public function stripSlashes(): self
278
    {
279 2
        return new self(stripslashes($this->value));
280
    }
281
282
    /**
283
     * Strip C-like slashes
284
     *
285
     * @return self
286
     */
287 2
    public function stripCSlashes(): self
288
    {
289 2
        return new self(stripcslashes($this->value));
290
    }
291
292
    /**
293
     * Return the word count
294
     *
295
     * @param string $charlist
296
     *
297
     * @return int
298
     */
299 2
    public function wordCount(string $charlist = ''): int
300
    {
301 2
        return (int) str_word_count(
302 2
            $this->value,
303 2
            0,
304
            $charlist
305
        );
306
    }
307
308
    /**
309
     * Return the collection of words
310
     *
311
     * @param string $charlist
312
     *
313
     * @return MapInterface<int, self>
0 ignored issues
show
Documentation introduced by
The doc-type MapInterface<int, could not be parsed: Expected "|" or "end of type", but got "<" at position 12. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
314
     */
315 2
    public function words(string $charlist = ''): MapInterface
316
    {
317 2
        $words = str_word_count($this->value, 2, $charlist);
318 2
        $map = new Map('int', self::class);
319
320 2
        foreach ($words as $position => $word) {
321 2
            $map = $map->put($position, new self($word));
2 ignored issues
show
Documentation introduced by
$position is of type integer|string, but the function expects a object<Innmind\Immutable\T>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Documentation introduced by
new self($word) is of type object<Innmind\Immutable\Str>, but the function expects a object<Innmind\Immutable\S>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
322
        }
323
324 2
        return $map;
325
    }
326
327
    /**
328
     * Split the string using a regular expression
329
     *
330
     * @param string $regex
331
     * @param int $limit
332
     *
333
     * @return StreamInterface<self>
0 ignored issues
show
Documentation introduced by
The doc-type StreamInterface<self> could not be parsed: Expected "|" or "end of type", but got "<" at position 15. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
334
     */
335 4
    public function pregSplit(string $regex, int $limit = -1): StreamInterface
336
    {
337 4
        $strings = preg_split($regex, $this->value, $limit);
338 4
        $stream = new Stream(self::class);
339
340 4
        foreach ($strings as $string) {
341 4
            $stream = $stream->add(new self($string));
1 ignored issue
show
Documentation introduced by
new self($string) is of type object<Innmind\Immutable\Str>, but the function expects a object<Innmind\Immutable\T>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
342
        }
343
344 4
        return $stream;
345
    }
346
347
    /**
348
     * Check if the string match the given regular expression
349
     *
350
     * @param string $regex
351
     * @param int $offset
352
     *
353
     * @throws Exception If the regex failed
354
     *
355
     * @return bool
356
     */
357 4
    public function matches(string $regex, int $offset = 0): bool
358
    {
359 4
        $matches = [];
360 4
        $value = preg_match($regex, $this->value, $matches, 0, $offset);
361
362 4
        if ($value === false) {
363 2
            throw new RegexException('', preg_last_error());
364
        }
365
366 2
        return (bool) $value;
367
    }
368
369
    /**
370
     * Return a collection of the elements matching the regex
371
     *
372
     * @deprecated replaced by self::capture, to be removed in 3.0
373
     *
374
     * @param string $regex
375
     * @param int $offset
376
     * @param int $flags
377
     *
378
     * @throws Exception If the regex failed
379
     *
380
     * @return MapInterface<scalar, self>
0 ignored issues
show
Documentation introduced by
The doc-type MapInterface<scalar, could not be parsed: Expected "|" or "end of type", but got "<" at position 12. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
381
     */
382 2
    public function getMatches(
383
        string $regex,
384
        int $offset = 0,
385
        int $flags = self::PREG_NO_FLAGS
386
    ): MapInterface {
387 2
        return $this->capture($regex, $offset, $flags);
388
    }
389
390
    /**
391
     * Return a collection of the elements matching the regex
392
     *
393
     * @param string $regex
394
     * @param int $offset
395
     * @param int $flags
396
     *
397
     * @throws Exception If the regex failed
398
     *
399
     * @return MapInterface<scalar, self>
0 ignored issues
show
Documentation introduced by
The doc-type MapInterface<scalar, could not be parsed: Expected "|" or "end of type", but got "<" at position 12. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
400
     */
401 6
    public function capture(
402
        string $regex,
403
        int $offset = 0,
404
        int $flags = self::PREG_NO_FLAGS
405
    ): MapInterface {
406 6
        $matches = [];
407 6
        $value = preg_match(
408
            $regex,
409 6
            $this->value,
410
            $matches,
411
            $flags,
412
            $offset
413
        );
414 6
        $map = new Map('scalar', self::class);
415
416 6
        foreach ($matches as $key => $match) {
417 4
            $map = $map->put($key, new self((string) $match));
2 ignored issues
show
Documentation introduced by
$key is of type integer, but the function expects a object<Innmind\Immutable\T>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Documentation introduced by
new self((string) $match) is of type object<Innmind\Immutable\Str>, but the function expects a object<Innmind\Immutable\S>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
418
        }
419
420 6
        if ($value === false) {
421 2
            throw new RegexException('', preg_last_error());
422
        }
423
424 4
        return $map;
425
    }
426
427
    /**
428
     * Replace part of the string by using a regular expression
429
     *
430
     * @param string $regex
431
     * @param string $replacement
432
     * @param int $limit
433
     *
434
     * @throws Exception If the regex failed
435
     *
436
     * @return self
437
     */
438 2
    public function pregReplace(
439
        string $regex,
440
        string $replacement,
441
        int $limit = -1
442
    ): self {
443 2
        $value = preg_replace(
444
            $regex,
445
            $replacement,
446 2
            $this->value,
447
            $limit
448
        );
449
450 2
        if ($value === null) {
451
            throw new RegexException('', preg_last_error());
452
        }
453
454 2
        return new self($value);
455
    }
456
457
    /**
458
     * Return part of the string
459
     *
460
     * @param int $start
461
     * @param int $length
462
     *
463
     * @return self
464
     */
465 2
    public function substring(int $start, int $length = null): self
466
    {
467 2
        if ($length === null) {
468 2
            $sub = substr($this->value, $start);
469
        } else {
470 2
            $sub = substr($this->value, $start, $length);
471
        }
472
473 2
        return new self($sub);
474
    }
475
476
    /**
477
     * Return a formatted string
478
     *
479
     * @return self
480
     */
481 2
    public function sprintf(...$values): self
482
    {
483 2
        array_unshift($values, $this->value);
484 2
        $formatted = call_user_func_array('sprintf', $values);
485
486 2
        return new self($formatted);
487
    }
488
489
    /**
490
     * Return the string with the first letter as uppercase
491
     *
492
     * @return self
493
     */
494 4
    public function ucfirst(): self
495
    {
496 4
        return new self(ucfirst($this->value));
497
    }
498
499
    /**
500
     * Return the string with the first letter as lowercase
501
     *
502
     * @return self
503
     */
504 2
    public function lcfirst(): self
505
    {
506 2
        return new self(lcfirst($this->value));
507
    }
508
509
    /**
510
     * Return a CamelCase representation of the string
511
     *
512
     * @return self
513
     */
514 2
    public function camelize(): self
515
    {
516 2
        return new self(
517
            (string) $this
518 2
                ->pregSplit('/_| /')
519 2
                ->map(function(self $part) {
520 2
                    return $part->ucfirst();
521 2
                })
522 2
                ->join('')
523
        );
524
    }
525
526
    /**
527
     * Append a string at the end of the current one
528
     *
529
     * @param string $string
530
     *
531
     * @return self
532
     */
533 2
    public function append(string $string): self
534
    {
535 2
        return new self((string) $this.$string);
536
    }
537
538
    /**
539
     * Prepend a string at the beginning of the current one
540
     *
541
     * @param string $string
542
     *
543
     * @return self
544
     */
545 2
    public function prepend(string $string): self
546
    {
547 2
        return new self($string.(string) $this);
548
    }
549
550
    /**
551
     * Check if the 2 strings are equal
552
     *
553
     * @param self $string
554
     *
555
     * @return bool
556
     */
557 56
    public function equals(self $string): bool
558
    {
559 56
        return (string) $this === (string) $string;
560
    }
561
562
    /**
563
     * Trim the string
564
     *
565
     * @param string $mask
566
     *
567
     * @return self
568
     */
569 2
    public function trim(string $mask = null): self
570
    {
571 2
        return new self(
572 2
            $mask === null ? trim((string) $this) : trim((string) $this, $mask)
573
        );
574
    }
575
576
    /**
577
     * Trim the right side of the string
578
     *
579
     * @param string $mask
580
     *
581
     * @return self
582
     */
583 2
    public function rightTrim(string $mask = null): self
584
    {
585 2
        return new self(
586 2
            $mask === null ? rtrim((string) $this) : rtrim((string) $this, $mask)
587
        );
588
    }
589
590
    /**
591
     * Trim the left side of the string
592
     *
593
     * @param string $mask
594
     *
595
     * @return self
596
     */
597 2
    public function leftTrim(string $mask = null): self
598
    {
599 2
        return new self(
600 2
            $mask === null ? ltrim((string) $this) : ltrim((string) $this, $mask)
601
        );
602
    }
603
604
    /**
605
     * Check if the given string is present in the current one
606
     *
607
     * @param string $value
608
     *
609
     * @return bool
610
     */
611 2
    public function contains(string $value): bool
612
    {
613
        try {
614 2
            $this->position($value);
615
616 2
            return true;
617 2
        } catch (SubstringException $e) {
618 2
            return false;
619
        }
620
    }
621
622
    /**
623
     * Quote regular expression characters
624
     *
625
     * @param string $delimiter
626
     *
627
     * @return self
628
     */
629 2
    public function pregQuote(string $delimiter = ''): self
630
    {
631 2
        return new self(preg_quote((string) $this, $delimiter));
632
    }
633
634
    /**
635
     * Pad the string
636
     *
637
     * @param int $length
638
     * @param string $character
639
     * @param int $direction
640
     *
641
     * @return self
642
     */
643 2
    private function pad(
644
        int $length,
645
        string $character = ' ',
646
        int $direction = self::PAD_RIGHT
647
    ): self {
648 2
        return new self(str_pad(
649 2
            $this->value,
650
            $length,
651
            $character,
652
            $direction
653
        ));
654
    }
655
}
656