Completed
Push — master ( 7c4b33...dbfb4d )
by Lars
01:43
created

Stringy::longestCommonSuffix()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 11
ccs 7
cts 7
cp 1
crap 1
rs 9.9
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stringy;
6
7
use voku\helper\AntiXSS;
8
use voku\helper\ASCII;
9
use voku\helper\EmailCheck;
10
use voku\helper\URLify;
11
use voku\helper\UTF8;
12
13
class Stringy implements \ArrayAccess, \Countable, \IteratorAggregate, \JsonSerializable
14
{
15
    /**
16
     * An instance's string.
17
     *
18
     * @var string
19
     */
20
    protected $str;
21
22
    /**
23
     * The string's encoding, which should be one of the mbstring module's
24
     * supported encodings.
25
     *
26
     * @var string
27
     */
28
    protected $encoding;
29
30
    /**
31
     * @var UTF8
32
     */
33
    private $utf8;
34
35
    /**
36
     * @var ASCII
37
     */
38
    private $ascii;
39
40
    /**
41
     * Initializes a Stringy object and assigns both str and encoding properties
42
     * the supplied values. $str is cast to a string prior to assignment, and if
43
     * $encoding is not specified, it defaults to mb_internal_encoding(). Throws
44
     * an InvalidArgumentException if the first argument is an array or object
45
     * without a __toString method.
46
     *
47
     * @param mixed  $str      [optional] <p>Value to modify, after being cast to string. Default: ''</p>
48
     * @param string $encoding [optional] <p>The character encoding. Fallback: 'UTF-8'</p>
49
     *
50
     * @throws \InvalidArgumentException
51
     *                                   <p>if an array or object without a
52
     *                                   __toString method is passed as the first argument</p>
53
     */
54 2236
    public function __construct($str = '', string $encoding = null)
55
    {
56 2236
        if (\is_array($str)) {
57 2
            throw new \InvalidArgumentException(
58 2
                'Passed value cannot be an array'
59
            );
60
        }
61
62
        if (
63 2234
            \is_object($str)
64
            &&
65 2234
            !\method_exists($str, '__toString')
66
        ) {
67 2
            throw new \InvalidArgumentException(
68 2
                'Passed object must have a __toString method'
69
            );
70
        }
71
72 2232
        $this->str = (string) $str;
73
74 2232
        static $ASCII = null;
75 2232
        if ($ASCII === null) {
76
            $ASCII = new ASCII();
77
        }
78 2232
        $this->ascii = $ASCII;
79
80 2232
        static $UTF8 = null;
81 2232
        if ($UTF8 === null) {
82
            $UTF8 = new UTF8();
83
        }
84 2232
        $this->utf8 = $UTF8;
85
86 2232
        if ($encoding !== 'UTF-8') {
87 1471
            $this->encoding = $this->utf8::normalize_encoding($encoding, 'UTF-8');
88
        } else {
89 1675
            $this->encoding = $encoding;
90
        }
91 2232
    }
92
93
    /**
94
     * Returns the value in $str.
95
     *
96
     * @return string
97
     *                <p>The current value of the $str property.</p>
98
     */
99 990
    public function __toString()
100
    {
101 990
        return (string) $this->str;
102
    }
103
104
    /**
105
     * Gets the substring after the first occurrence of a separator.
106
     * If no match is found returns new empty Stringy object.
107
     *
108
     * @param string $separator
109
     *
110
     * @return static
111
     */
112 2
    public function afterFirst(string $separator): self
113
    {
114 2
        return static::create(
115 2
            $this->utf8::str_substr_after_first_separator(
116 2
                $this->str,
117 2
                $separator,
118 2
                $this->encoding
119
            )
120
        );
121
    }
122
123
    /**
124
     * Gets the substring after the first occurrence of a separator.
125
     * If no match is found returns new empty Stringy object.
126
     *
127
     * @param string $separator
128
     *
129
     * @return static
130
     */
131 1
    public function afterFirstIgnoreCase(string $separator): self
132
    {
133 1
        return static::create(
134 1
            $this->utf8::str_isubstr_after_first_separator(
135 1
                $this->str,
136 1
                $separator,
137 1
                $this->encoding
138
            )
139
        );
140
    }
141
142
    /**
143
     * Gets the substring after the last occurrence of a separator.
144
     * If no match is found returns new empty Stringy object.
145
     *
146
     * @param string $separator
147
     *
148
     * @return static
149
     */
150 1
    public function afterLast(string $separator): self
151
    {
152 1
        return static::create(
153 1
            $this->utf8::str_substr_after_last_separator(
154 1
                $this->str,
155 1
                $separator,
156 1
                $this->encoding
157
            )
158
        );
159
    }
160
161
    /**
162
     * Gets the substring after the last occurrence of a separator.
163
     * If no match is found returns new empty Stringy object.
164
     *
165
     * @param string $separator
166
     *
167
     * @return static
168
     */
169 1
    public function afterLastIgnoreCase(string $separator): self
170
    {
171 1
        return static::create(
172 1
            $this->utf8::str_isubstr_after_last_separator(
173 1
                $this->str,
174 1
                $separator,
175 1
                $this->encoding
176
            )
177
        );
178
    }
179
180
    /**
181
     * Returns a new string with $string appended.
182
     *
183
     * @param string ...$suffix <p>The string to append.</p>
184
     *
185
     * @return static
186
     *                <p>Object with appended $string.</p>
187
     *
188
     * @noinspection PhpDocSignatureInspection
189
     */
190 8 View Code Duplication
    public function append(string ...$suffix): self
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...
191
    {
192 8
        if (\count($suffix) <= 1) {
193
            /** @noinspection CallableParameterUseCaseInTypeContextInspection */
194 8
            $suffix = $suffix[0];
195
        } else {
196
            /** @noinspection CallableParameterUseCaseInTypeContextInspection */
197
            $suffix = \implode('', $suffix);
198
        }
199
200 8
        return static::create($this->str . $suffix, $this->encoding);
201
    }
202
203
    /**
204
     * Append an password (limited to chars that are good readable).
205
     *
206
     * @param int $length <p>Length of the random string.</p>
207
     *
208
     * @return static
209
     *                <p>Object with appended password.</p>
210
     */
211 1
    public function appendPassword(int $length): self
212
    {
213 1
        return $this->appendRandomString(
214 1
            $length,
215 1
            '2346789bcdfghjkmnpqrtvwxyzBCDFGHJKLMNPQRTVWXYZ!?_#'
216
        );
217
    }
218
219
    /**
220
     * Append an random string.
221
     *
222
     * @param int    $length        <p>Length of the random string.</p>
223
     * @param string $possibleChars [optional] <p>Characters string for the random selection.</p>
224
     *
225
     * @return static
226
     *                <p>Object with appended random string.</p>
227
     */
228 2
    public function appendRandomString(int $length, string $possibleChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'): self
229
    {
230 2
        $str = $this->utf8::get_random_string($length, $possibleChars);
231
232 2
        return $this->append($str);
233
    }
234
235
    /**
236
     * Append an unique identifier.
237
     *
238
     * @param int|string $entropyExtra [optional] <p>Extra entropy via a string or int value.</p>
239
     * @param bool       $md5          [optional] <p>Return the unique identifier as md5-hash? Default: true</p>
240
     *
241
     * @return static
242
     *                <p>Object with appended unique identifier as md5-hash.</p>
243
     */
244 1
    public function appendUniqueIdentifier($entropyExtra = '', bool $md5 = true): self
245
    {
246 1
        return $this->append(
247 1
            $this->utf8::get_unique_string($entropyExtra, $md5)
248
        );
249
    }
250
251
    /**
252
     * Returns the character at $index, with indexes starting at 0.
253
     *
254
     * @param int $index <p>Position of the character.</p>
255
     *
256
     * @return static
257
     *                <p>The character at $index.</p>
258
     */
259 16
    public function at(int $index): self
260
    {
261 16
        return static::create($this->utf8::char_at($this->str, $index), $this->encoding);
262
    }
263
264
    /**
265
     * Gets the substring before the first occurrence of a separator.
266
     * If no match is found returns new empty Stringy object.
267
     *
268
     * @param string $separator
269
     *
270
     * @return static
271
     */
272 1
    public function beforeFirst(string $separator): self
273
    {
274 1
        return static::create(
275 1
            $this->utf8::str_substr_before_first_separator(
276 1
                $this->str,
277 1
                $separator,
278 1
                $this->encoding
279
            )
280
        );
281
    }
282
283
    /**
284
     * Gets the substring before the first occurrence of a separator.
285
     * If no match is found returns new empty Stringy object.
286
     *
287
     * @param string $separator
288
     *
289
     * @return static
290
     */
291 1
    public function beforeFirstIgnoreCase(string $separator): self
292
    {
293 1
        return static::create(
294 1
            $this->utf8::str_isubstr_before_first_separator(
295 1
                $this->str,
296 1
                $separator,
297 1
                $this->encoding
298
            )
299
        );
300
    }
301
302
    /**
303
     * Gets the substring before the last occurrence of a separator.
304
     * If no match is found returns new empty Stringy object.
305
     *
306
     * @param string $separator
307
     *
308
     * @return static
309
     */
310 1
    public function beforeLast(string $separator): self
311
    {
312 1
        return static::create(
313 1
            $this->utf8::str_substr_before_last_separator(
314 1
                $this->str,
315 1
                $separator,
316 1
                $this->encoding
317
            )
318
        );
319
    }
320
321
    /**
322
     * Gets the substring before the last occurrence of a separator.
323
     * If no match is found returns new empty Stringy object.
324
     *
325
     * @param string $separator
326
     *
327
     * @return static
328
     */
329 1
    public function beforeLastIgnoreCase(string $separator): self
330
    {
331 1
        return static::create(
332 1
            $this->utf8::str_isubstr_before_last_separator(
333 1
                $this->str,
334 1
                $separator,
335 1
                $this->encoding
336
            )
337
        );
338
    }
339
340
    /**
341
     * Returns the substring between $start and $end, if found, or an empty
342
     * string. An optional offset may be supplied from which to begin the
343
     * search for the start string.
344
     *
345
     * @param string $start  <p>Delimiter marking the start of the substring.</p>
346
     * @param string $end    <p>Delimiter marking the end of the substring.</p>
347
     * @param int    $offset [optional] <p>Index from which to begin the search. Default: 0</p>
348
     *
349
     * @return static
350
     *                <p>Object whose $str is a substring between $start and $end.</p>
351
     */
352 32
    public function between(string $start, string $end, int $offset = null): self
353
    {
354
        /** @noinspection UnnecessaryCastingInspection */
355 32
        $str = $this->utf8::between(
356 32
            $this->str,
357 32
            $start,
358 32
            $end,
359 32
            (int) $offset,
360 32
            $this->encoding
361
        );
362
363 32
        return static::create($str, $this->encoding);
364
    }
365
366
    /**
367
     * Returns a camelCase version of the string. Trims surrounding spaces,
368
     * capitalizes letters following digits, spaces, dashes and underscores,
369
     * and removes spaces, dashes, as well as underscores.
370
     *
371
     * @return static
372
     *                <p>Object with $str in camelCase.</p>
373
     */
374 38
    public function camelize(): self
375
    {
376 38
        return static::create(
377 38
            $this->utf8::str_camelize($this->str, $this->encoding),
378 38
            $this->encoding
379
        );
380
    }
381
382
    /**
383
     * Returns the string with the first letter of each word capitalized,
384
     * except for when the word is a name which shouldn't be capitalized.
385
     *
386
     * @return static
387
     *                <p>Object with $str capitalized.</p>
388
     */
389 39
    public function capitalizePersonalName(): self
390
    {
391 39
        return static::create(
392 39
            $this->utf8::str_capitalize_name($this->str),
393 39
            $this->encoding
394
        );
395
    }
396
397
    /**
398
     * Returns an array consisting of the characters in the string.
399
     *
400
     * @return string[]
401
     *                  <p>An array of string chars.</p>
402
     */
403 8
    public function chars(): array
404
    {
405 8
        return $this->utf8::str_split($this->str);
406
    }
407
408
    /**
409
     * Splits the string into chunks of Stringy objects.
410
     *
411
     * @param int $length
412
     *
413
     * @return CollectionStringy|static[]
414
     *                                    <p>An collection of Stringy objects.</p>
415
     */
416 5
    public function chunk(int $length = 1): CollectionStringy
417
    {
418 5
        if ($length < 1) {
419
            throw new \InvalidArgumentException('The chunk length must be greater than zero.');
420
        }
421
422 5
        if ($this->str === '') {
423 1
            return CollectionStringy::create();
424
        }
425
426 4
        $chunks = $this->utf8::str_split($this->str, $length);
427 4
        foreach ($chunks as $i => &$value) {
428 4
            $value = static::create($value, $this->encoding);
429
        }
430
431 4
        return CollectionStringy::create($chunks);
432
    }
433
434
    /**
435
     * Trims the string and replaces consecutive whitespace characters with a
436
     * single space. This includes tabs and newline characters, as well as
437
     * multibyte whitespace such as the thin space and ideographic space.
438
     *
439
     * @return static
440
     *                <p>Object with a trimmed $str and condensed whitespace.</p>
441
     */
442 26
    public function collapseWhitespace(): self
443
    {
444 26
        return static::create(
445 26
            $this->utf8::collapse_whitespace($this->str),
446 26
            $this->encoding
447
        );
448
    }
449
450
    /**
451
     * Returns true if the string contains $needle, false otherwise. By default
452
     * the comparison is case-sensitive, but can be made insensitive by setting
453
     * $caseSensitive to false.
454
     *
455
     * @param string $needle        <p>Substring to look for.</p>
456
     * @param bool   $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
457
     *
458
     * @return bool
459
     *              <p>Whether or not $str contains $needle.</p>
460
     */
461 42
    public function contains(string $needle, bool $caseSensitive = true): bool
462
    {
463 42
        return $this->utf8::str_contains(
464 42
            $this->str,
465 42
            $needle,
466 42
            $caseSensitive
467
        );
468
    }
469
470
    /**
471
     * Returns true if the string contains all $needles, false otherwise. By
472
     * default the comparison is case-sensitive, but can be made insensitive by
473
     * setting $caseSensitive to false.
474
     *
475
     * @param array $needles       <p>SubStrings to look for.</p>
476
     * @param bool  $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
477
     *
478
     * @return bool
479
     *              <p>Whether or not $str contains $needle.</p>
480
     */
481 87
    public function containsAll(array $needles, bool $caseSensitive = true): bool
482
    {
483 87
        return $this->utf8::str_contains_all(
484 87
            $this->str,
485 87
            $needles,
486 87
            $caseSensitive
487
        );
488
    }
489
490
    /**
491
     * Returns true if the string contains any $needles, false otherwise. By
492
     * default the comparison is case-sensitive, but can be made insensitive by
493
     * setting $caseSensitive to false.
494
     *
495
     * @param array $needles       <p>SubStrings to look for.</p>
496
     * @param bool  $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
497
     *
498
     * @return bool
499
     *              <p>Whether or not $str contains $needle.</p>
500
     */
501 86
    public function containsAny(array $needles, bool $caseSensitive = true): bool
502
    {
503 86
        return $this->utf8::str_contains_any(
504 86
            $this->str,
505 86
            $needles,
506 86
            $caseSensitive
507
        );
508
    }
509
510
    /**
511
     * Returns the length of the string, implementing the countable interface.
512
     *
513
     * @return int
514
     *             <p>The number of characters in the string, given the encoding.</p>
515
     */
516 2
    public function count(): int
517
    {
518 2
        return $this->length();
519
    }
520
521
    /**
522
     * Returns the number of occurrences of $substring in the given string.
523
     * By default, the comparison is case-sensitive, but can be made insensitive
524
     * by setting $caseSensitive to false.
525
     *
526
     * @param string $substring     <p>The substring to search for.</p>
527
     * @param bool   $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
528
     *
529
     * @return int
530
     */
531 30
    public function countSubstr(string $substring, bool $caseSensitive = true): int
532
    {
533 30
        return $this->utf8::substr_count_simple(
534 30
            $this->str,
535 30
            $substring,
536 30
            $caseSensitive,
537 30
            $this->encoding
538
        );
539
    }
540
541
    /**
542
     * Creates a Stringy object and assigns both str and encoding properties
543
     * the supplied values. $str is cast to a string prior to assignment, and if
544
     * $encoding is not specified, it defaults to mb_internal_encoding(). It
545
     * then returns the initialized object. Throws an InvalidArgumentException
546
     * if the first argument is an array or object without a __toString method.
547
     *
548
     * @param mixed  $str      [optional] <p>Value to modify, after being cast to string. Default: ''</p>
549
     * @param string $encoding [optional] <p>The character encoding. Fallback: 'UTF-8'</p>
550
     *
551
     * @throws \InvalidArgumentException
552
     *                                   <p>if an array or object without a
553
     *                                   __toString method is passed as the first argument</p>
554
     *
555
     * @return static
556
     *                <p>A Stringy object.</p>
557
     */
558 2214
    public static function create($str = '', string $encoding = null): self
559
    {
560 2214
        return new static($str, $encoding);
561
    }
562
563
    /**
564
     * Returns a lowercase and trimmed string separated by dashes. Dashes are
565
     * inserted before uppercase characters (with the exception of the first
566
     * character of the string), and in place of spaces as well as underscores.
567
     *
568
     * @return static
569
     *                <p>Object with a dasherized $str</p>
570
     */
571 38
    public function dasherize(): self
572
    {
573 38
        return static::create(
574 38
            $this->utf8::str_dasherize($this->str),
575 38
            $this->encoding
576
        );
577
    }
578
579
    /**
580
     * Returns a lowercase and trimmed string separated by the given delimiter.
581
     * Delimiters are inserted before uppercase characters (with the exception
582
     * of the first character of the string), and in place of spaces, dashes,
583
     * and underscores. Alpha delimiters are not converted to lowercase.
584
     *
585
     * @param string $delimiter <p>Sequence used to separate parts of the string.</p>
586
     *
587
     * @return static
588
     *                <p>Object with a delimited $str.</p>
589
     */
590 60
    public function delimit(string $delimiter): self
591
    {
592 60
        return static::create(
593 60
            $this->utf8::str_delimit($this->str, $delimiter),
594 60
            $this->encoding
595
        );
596
    }
597
598
    /**
599
     * Returns true if the string ends with $substring, false otherwise. By
600
     * default, the comparison is case-sensitive, but can be made insensitive
601
     * by setting $caseSensitive to false.
602
     *
603
     * @param string $substring     <p>The substring to look for.</p>
604
     * @param bool   $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
605
     *
606
     * @return bool
607
     *              <p>Whether or not $str ends with $substring.</p>
608
     */
609 54
    public function endsWith(string $substring, bool $caseSensitive = true): bool
610
    {
611 54
        if ($caseSensitive) {
612 30
            return $this->utf8::str_ends_with($this->str, $substring);
613
        }
614
615 24
        return $this->utf8::str_iends_with($this->str, $substring);
616
    }
617
618
    /**
619
     * Returns true if the string ends with any of $substrings, false otherwise.
620
     * By default, the comparison is case-sensitive, but can be made insensitive
621
     * by setting $caseSensitive to false.
622
     *
623
     * @param string[] $substrings    <p>Substrings to look for.</p>
624
     * @param bool     $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
625
     *
626
     * @return bool
627
     *              <p>Whether or not $str ends with $substring.</p>
628
     */
629 22
    public function endsWithAny(array $substrings, bool $caseSensitive = true): bool
630
    {
631 22
        if ($caseSensitive) {
632 14
            return $this->utf8::str_ends_with_any($this->str, $substrings);
633
        }
634
635 8
        return $this->utf8::str_iends_with_any($this->str, $substrings);
636
    }
637
638
    /**
639
     * Ensures that the string begins with $substring. If it doesn't, it's
640
     * prepended.
641
     *
642
     * @param string $substring <p>The substring to add if not present.</p>
643
     *
644
     * @return static
645
     *                <p>Object with its $str prefixed by the $substring.</p>
646
     */
647 20
    public function ensureLeft(string $substring): self
648
    {
649 20
        return static::create(
650 20
            $this->utf8::str_ensure_left($this->str, $substring),
651 20
            $this->encoding
652
        );
653
    }
654
655
    /**
656
     * Ensures that the string ends with $substring. If it doesn't, it's appended.
657
     *
658
     * @param string $substring <p>The substring to add if not present.</p>
659
     *
660
     * @return static
661
     *                <p>Object with its $str suffixed by the $substring.</p>
662
     */
663 20
    public function ensureRight(string $substring): self
664
    {
665 20
        return static::create(
666 20
            $this->utf8::str_ensure_right($this->str, $substring),
667 20
            $this->encoding
668
        );
669
    }
670
671
    /**
672
     * Create a escape html version of the string via "htmlspecialchars()".
673
     *
674
     * @return static
675
     */
676 6
    public function escape(): self
677
    {
678 6
        return static::create(
679 6
            $this->utf8::htmlspecialchars(
680 6
                $this->str,
681 6
                \ENT_QUOTES | \ENT_SUBSTITUTE,
682 6
                $this->encoding
683
            ),
684 6
            $this->encoding
685
        );
686
    }
687
688
    /**
689
     * Create an extract from a sentence, so if the search-string was found, it try to centered in the output.
690
     *
691
     * @param string   $search
692
     * @param int|null $length                 [optional] <p>Default: null === text->length / 2</p>
693
     * @param string   $replacerForSkippedText [optional] <p>Default: …</p>
694
     *
695
     * @return static
696
     */
697 1
    public function extractText(string $search = '', int $length = null, string $replacerForSkippedText = '…'): self
698
    {
699 1
        return static::create(
700 1
            $this->utf8::extract_text(
701 1
                $this->str,
702 1
                $search,
703 1
                $length,
704 1
                $replacerForSkippedText,
705 1
                $this->encoding
706
            ),
707 1
            $this->encoding
708
        );
709
    }
710
711
    /**
712
     * Returns the first $n characters of the string.
713
     *
714
     * @param int $n <p>Number of characters to retrieve from the start.</p>
715
     *
716
     * @return static
717
     *                <p>Object with its $str being the first $n chars.</p>
718
     */
719 25
    public function first(int $n): self
720
    {
721 25
        return static::create(
722 25
            $this->utf8::first_char($this->str, $n, $this->encoding),
723 25
            $this->encoding
724
        );
725
    }
726
727
    /**
728
     * Return a formatted string via sprintf + named parameters via array syntax.
729
     *
730
     * <p>
731
     * <br>
732
     * It will use "sprintf()" so you can use e.g.:
733
     * <br>
734
     * <br><pre>s('There are %d monkeys in the %s')->format(5, 'tree');</pre>
735
     * <br>
736
     * <br><pre>s('There are %2$d monkeys in the %1$s')->format('tree', 5);</pre>
737
     * <br>
738
     * <br>
739
     * But you can also use named parameter via array syntax e.g.:
740
     * <br>
741
     * <br><pre>s('There are %:count monkeys in the %:location')->format(['count' => 5, 'location' => 'tree');</pre>
742
     * </p>
743
     *
744
     * @param mixed ...$args [optional]
745
     *
746
     * @return static
747
     *                <p>A Stringy object produced according to the formatting string
748
     *                format.</p>
749
     */
750 5
    public function format(...$args): self
751
    {
752
        // init
753 5
        $str = $this->str;
754
755 5
        if (\strpos($this->str, '%:') !== false) {
756 4
            $offset = null;
757 4
            $replacement = null;
758
            /** @noinspection AlterInForeachInspection */
759 4
            foreach ($args as $key => &$arg) {
760 4
                if (!\is_array($arg)) {
761 2
                    continue;
762
                }
763
764 4
                foreach ($arg as $name => $param) {
765 4
                    $name = (string) $name;
766
767 4
                    if (\strpos($name, '%:') !== 0) {
768 4
                        $nameTmp = '%:' . $name;
769
                    } else {
770
                        $nameTmp = $name;
771
                    }
772
773 4
                    if ($offset === null) {
774 4
                        $offset = \strpos($str, $nameTmp);
775
                    } else {
776 3
                        $offset = \strpos($str, $nameTmp, $offset + \strlen((string) $replacement));
777
                    }
778 4
                    if ($offset === false) {
779 2
                        continue;
780
                    }
781
782 4
                    unset($arg[$name]);
783
784 4
                    $str = \substr_replace($str, $param, $offset, \strlen($nameTmp));
785
                }
786
787 4
                unset($args[$key]);
788
            }
789
        }
790
791 5
        $str = \str_replace('%:', '%%:', $str);
792
793 5
        return static::create(
794 5
            \sprintf($str, ...$args),
795 5
            $this->encoding
796
        );
797
    }
798
799
    /**
800
     * Returns the encoding used by the Stringy object.
801
     *
802
     * @return string
803
     *                <p>The current value of the $encoding property.</p>
804
     */
805 5
    public function getEncoding(): string
806
    {
807 5
        return $this->encoding;
808
    }
809
810
    /**
811
     * Returns a new ArrayIterator, thus implementing the IteratorAggregate
812
     * interface. The ArrayIterator's constructor is passed an array of chars
813
     * in the multibyte string. This enables the use of foreach with instances
814
     * of Stringy\Stringy.
815
     *
816
     * @return \ArrayIterator
817
     *                        <p>An iterator for the characters in the string.</p>
818
     */
819 2
    public function getIterator(): \ArrayIterator
820
    {
821 2
        return new \ArrayIterator($this->chars());
822
    }
823
824
    /**
825
     * Returns true if the string contains a lower case char, false otherwise.
826
     *
827
     * @return bool
828
     *              <p>Whether or not the string contains a lower case character.</p>
829
     */
830 24
    public function hasLowerCase(): bool
831
    {
832 24
        return $this->utf8::has_lowercase($this->str);
833
    }
834
835
    /**
836
     * Returns true if the string contains an upper case char, false otherwise.
837
     *
838
     * @return bool
839
     *              <p>Whether or not the string contains an upper case character.</p>
840
     */
841 24
    public function hasUpperCase(): bool
842
    {
843 24
        return $this->utf8::has_uppercase($this->str);
844
    }
845
846
    /**
847
     * Convert all HTML entities to their applicable characters.
848
     *
849
     * @param int $flags [optional] <p>
850
     *                   A bitmask of one or more of the following flags, which specify how to handle quotes and
851
     *                   which document type to use. The default is ENT_COMPAT.
852
     *                   <table>
853
     *                   Available <i>flags</i> constants
854
     *                   <tr valign="top">
855
     *                   <td>Constant Name</td>
856
     *                   <td>Description</td>
857
     *                   </tr>
858
     *                   <tr valign="top">
859
     *                   <td><b>ENT_COMPAT</b></td>
860
     *                   <td>Will convert double-quotes and leave single-quotes alone.</td>
861
     *                   </tr>
862
     *                   <tr valign="top">
863
     *                   <td><b>ENT_QUOTES</b></td>
864
     *                   <td>Will convert both double and single quotes.</td>
865
     *                   </tr>
866
     *                   <tr valign="top">
867
     *                   <td><b>ENT_NOQUOTES</b></td>
868
     *                   <td>Will leave both double and single quotes unconverted.</td>
869
     *                   </tr>
870
     *                   <tr valign="top">
871
     *                   <td><b>ENT_HTML401</b></td>
872
     *                   <td>
873
     *                   Handle code as HTML 4.01.
874
     *                   </td>
875
     *                   </tr>
876
     *                   <tr valign="top">
877
     *                   <td><b>ENT_XML1</b></td>
878
     *                   <td>
879
     *                   Handle code as XML 1.
880
     *                   </td>
881
     *                   </tr>
882
     *                   <tr valign="top">
883
     *                   <td><b>ENT_XHTML</b></td>
884
     *                   <td>
885
     *                   Handle code as XHTML.
886
     *                   </td>
887
     *                   </tr>
888
     *                   <tr valign="top">
889
     *                   <td><b>ENT_HTML5</b></td>
890
     *                   <td>
891
     *                   Handle code as HTML 5.
892
     *                   </td>
893
     *                   </tr>
894
     *                   </table>
895
     *                   </p>
896
     *
897
     * @return static
898
     *                <p>Object with the resulting $str after being html decoded.</p>
899
     */
900 10 View Code Duplication
    public function htmlDecode(int $flags = \ENT_COMPAT): self
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...
901
    {
902 10
        return static::create(
903 10
            $this->utf8::html_entity_decode(
904 10
                $this->str,
905 10
                $flags,
906 10
                $this->encoding
907
            ),
908 10
            $this->encoding
909
        );
910
    }
911
912
    /**
913
     * Convert all applicable characters to HTML entities.
914
     *
915
     * @param int $flags [optional] <p>
916
     *                   A bitmask of one or more of the following flags, which specify how to handle quotes and
917
     *                   which document type to use. The default is ENT_COMPAT.
918
     *                   <table>
919
     *                   Available <i>flags</i> constants
920
     *                   <tr valign="top">
921
     *                   <td>Constant Name</td>
922
     *                   <td>Description</td>
923
     *                   </tr>
924
     *                   <tr valign="top">
925
     *                   <td><b>ENT_COMPAT</b></td>
926
     *                   <td>Will convert double-quotes and leave single-quotes alone.</td>
927
     *                   </tr>
928
     *                   <tr valign="top">
929
     *                   <td><b>ENT_QUOTES</b></td>
930
     *                   <td>Will convert both double and single quotes.</td>
931
     *                   </tr>
932
     *                   <tr valign="top">
933
     *                   <td><b>ENT_NOQUOTES</b></td>
934
     *                   <td>Will leave both double and single quotes unconverted.</td>
935
     *                   </tr>
936
     *                   <tr valign="top">
937
     *                   <td><b>ENT_HTML401</b></td>
938
     *                   <td>
939
     *                   Handle code as HTML 4.01.
940
     *                   </td>
941
     *                   </tr>
942
     *                   <tr valign="top">
943
     *                   <td><b>ENT_XML1</b></td>
944
     *                   <td>
945
     *                   Handle code as XML 1.
946
     *                   </td>
947
     *                   </tr>
948
     *                   <tr valign="top">
949
     *                   <td><b>ENT_XHTML</b></td>
950
     *                   <td>
951
     *                   Handle code as XHTML.
952
     *                   </td>
953
     *                   </tr>
954
     *                   <tr valign="top">
955
     *                   <td><b>ENT_HTML5</b></td>
956
     *                   <td>
957
     *                   Handle code as HTML 5.
958
     *                   </td>
959
     *                   </tr>
960
     *                   </table>
961
     *                   </p>
962
     *
963
     * @return static
964
     *                <p>Object with the resulting $str after being html encoded.</p>
965
     */
966 10 View Code Duplication
    public function htmlEncode(int $flags = \ENT_COMPAT): self
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...
967
    {
968 10
        return static::create(
969 10
            $this->utf8::htmlentities(
970 10
                $this->str,
971 10
                $flags,
972 10
                $this->encoding
973
            ),
974 10
            $this->encoding
975
        );
976
    }
977
978
    /**
979
     * Capitalizes the first word of the string, replaces underscores with
980
     * spaces, and strips '_id'.
981
     *
982
     * @return static
983
     *                <p>Object with a humanized $str.</p>
984
     */
985 6
    public function humanize(): self
986
    {
987 6
        return static::create(
988 6
            $this->utf8::str_humanize($this->str),
989 6
            $this->encoding
990
        );
991
    }
992
993
    /**
994
     * Returns the index of the first occurrence of $needle in the string,
995
     * and false if not found. Accepts an optional offset from which to begin
996
     * the search.
997
     *
998
     * @param string $needle <p>Substring to look for.</p>
999
     * @param int    $offset [optional] <p>Offset from which to search. Default: 0</p>
1000
     *
1001
     * @return false|int
1002
     *                   <p>The occurrence's <strong>index</strong> if found, otherwise <strong>false</strong>.</p>
1003
     */
1004 21
    public function indexOf(string $needle, int $offset = 0)
1005
    {
1006 21
        return $this->utf8::strpos(
1007 21
            $this->str,
1008 21
            $needle,
1009 21
            $offset,
1010 21
            $this->encoding
1011
        );
1012
    }
1013
1014
    /**
1015
     * Returns the index of the first occurrence of $needle in the string,
1016
     * and false if not found. Accepts an optional offset from which to begin
1017
     * the search.
1018
     *
1019
     * @param string $needle <p>Substring to look for.</p>
1020
     * @param int    $offset [optional] <p>Offset from which to search. Default: 0</p>
1021
     *
1022
     * @return false|int
1023
     *                   <p>The occurrence's <strong>index</strong> if found, otherwise <strong>false</strong>.</p>
1024
     */
1025 10
    public function indexOfIgnoreCase(string $needle, int $offset = 0)
1026
    {
1027 10
        return $this->utf8::stripos(
1028 10
            $this->str,
1029 10
            $needle,
1030 10
            $offset,
1031 10
            $this->encoding
1032
        );
1033
    }
1034
1035
    /**
1036
     * Returns the index of the last occurrence of $needle in the string,
1037
     * and false if not found. Accepts an optional offset from which to begin
1038
     * the search. Offsets may be negative to count from the last character
1039
     * in the string.
1040
     *
1041
     * @param string $needle <p>Substring to look for.</p>
1042
     * @param int    $offset [optional] <p>Offset from which to search. Default: 0</p>
1043
     *
1044
     * @return false|int
1045
     *                   <p>The last occurrence's <strong>index</strong> if found, otherwise <strong>false</strong>.</p>
1046
     */
1047 21
    public function indexOfLast(string $needle, int $offset = 0)
1048
    {
1049 21
        return $this->utf8::strrpos(
1050 21
            $this->str,
1051 21
            $needle,
1052 21
            $offset,
1053 21
            $this->encoding
1054
        );
1055
    }
1056
1057
    /**
1058
     * Returns the index of the last occurrence of $needle in the string,
1059
     * and false if not found. Accepts an optional offset from which to begin
1060
     * the search. Offsets may be negative to count from the last character
1061
     * in the string.
1062
     *
1063
     * @param string $needle <p>Substring to look for.</p>
1064
     * @param int    $offset [optional] <p>Offset from which to search. Default: 0</p>
1065
     *
1066
     * @return false|int
1067
     *                   <p>The last occurrence's <strong>index</strong> if found, otherwise <strong>false</strong>.</p>
1068
     */
1069 10
    public function indexOfLastIgnoreCase(string $needle, int $offset = 0)
1070
    {
1071 10
        return $this->utf8::strripos(
1072 10
            $this->str,
1073 10
            $needle,
1074 10
            $offset,
1075 10
            $this->encoding
1076
        );
1077
    }
1078
1079
    /**
1080
     * Inserts $substring into the string at the $index provided.
1081
     *
1082
     * @param string $substring <p>String to be inserted.</p>
1083
     * @param int    $index     <p>The index at which to insert the substring.</p>
1084
     *
1085
     * @return static
1086
     *                <p>Object with the resulting $str after the insertion.</p>
1087
     */
1088 16
    public function insert(string $substring, int $index): self
1089
    {
1090 16
        return static::create(
1091 16
            $this->utf8::str_insert(
1092 16
                $this->str,
1093 16
                $substring,
1094 16
                $index,
1095 16
                $this->encoding
1096
            ),
1097 16
            $this->encoding
1098
        );
1099
    }
1100
1101
    /**
1102
     * Returns true if the string contains the $pattern, otherwise false.
1103
     *
1104
     * WARNING: Asterisks ("*") are translated into (".*") zero-or-more regular
1105
     * expression wildcards.
1106
     *
1107
     * @credit Originally from Laravel, thanks Taylor.
1108
     *
1109
     * @param string $pattern <p>The string or pattern to match against.</p>
1110
     *
1111
     * @return bool
1112
     *              <p>Whether or not we match the provided pattern.</p>
1113
     */
1114 13
    public function is(string $pattern): bool
1115
    {
1116 13
        if ($this->toString() === $pattern) {
1117 1
            return true;
1118
        }
1119
1120 12
        $quotedPattern = \preg_quote($pattern, '/');
1121 12
        $replaceWildCards = \str_replace('\*', '.*', $quotedPattern);
1122
1123 12
        return $this->matchesPattern('^' . $replaceWildCards . '\z');
1124
    }
1125
1126
    /**
1127
     * Returns true if the string contains only alphabetic chars, false otherwise.
1128
     *
1129
     * @return bool
1130
     *              <p>Whether or not $str contains only alphabetic chars.</p>
1131
     */
1132 20
    public function isAlpha(): bool
1133
    {
1134 20
        return $this->utf8::is_alpha($this->str);
1135
    }
1136
1137
    /**
1138
     * Returns true if the string contains only alphabetic and numeric chars, false otherwise.
1139
     *
1140
     * @return bool
1141
     *              <p>Whether or not $str contains only alphanumeric chars.</p>
1142
     */
1143 26
    public function isAlphanumeric(): bool
1144
    {
1145 26
        return $this->utf8::is_alphanumeric($this->str);
1146
    }
1147
1148
    /**
1149
     * Returns true if the string is base64 encoded, false otherwise.
1150
     *
1151
     * @param bool $emptyStringIsValid
1152
     *
1153
     * @return bool
1154
     *              <p>Whether or not $str is base64 encoded.</p>
1155
     */
1156 14
    public function isBase64($emptyStringIsValid = true): bool
1157
    {
1158 14
        return $this->utf8::is_base64($this->str, $emptyStringIsValid);
1159
    }
1160
1161
    /**
1162
     * Returns true if the string contains only whitespace chars, false otherwise.
1163
     *
1164
     * @return bool
1165
     *              <p>Whether or not $str contains only whitespace characters.</p>
1166
     */
1167 30
    public function isBlank(): bool
1168
    {
1169 30
        return $this->utf8::is_blank($this->str);
1170
    }
1171
1172
    /**
1173
     * Returns true if the string contains a valid E-Mail address, false otherwise.
1174
     *
1175
     * @param bool $useExampleDomainCheck   [optional] <p>Default: false</p>
1176
     * @param bool $useTypoInDomainCheck    [optional] <p>Default: false</p>
1177
     * @param bool $useTemporaryDomainCheck [optional] <p>Default: false</p>
1178
     * @param bool $useDnsCheck             [optional] <p>Default: false</p>
1179
     *
1180
     * @return bool
1181
     *              <p>Whether or not $str contains a valid E-Mail address.</p>
1182
     */
1183 1
    public function isEmail(bool $useExampleDomainCheck = false, bool $useTypoInDomainCheck = false, bool $useTemporaryDomainCheck = false, bool $useDnsCheck = false): bool
1184
    {
1185 1
        return EmailCheck::isValid($this->str, $useExampleDomainCheck, $useTypoInDomainCheck, $useTemporaryDomainCheck, $useDnsCheck);
1186
    }
1187
1188
    /**
1189
     * Determine whether the string is considered to be empty.
1190
     *
1191
     * A variable is considered empty if it does not exist or if its value equals FALSE.
1192
     *
1193
     * @return bool
1194
     *              <p>Whether or not $str is empty().</p>
1195
     */
1196 5
    public function isEmpty(): bool
1197
    {
1198 5
        return $this->utf8::is_empty($this->str);
1199
    }
1200
1201
    /**
1202
     * Determine whether the string is equals to $str.
1203
     *
1204
     * @param string ...$str <p>The string to compare.</p>
1205
     *
1206
     * @return bool
1207
     *              <p>Whether or not $str is equals.</p>
1208
     *
1209
     * @noinspection PhpDocSignatureInspection
1210
     */
1211 7
    public function isEquals(string ...$str): bool
1212
    {
1213 7
        foreach ($str as $strTmp) {
1214 7
            if ($this->str !== $strTmp) {
1215 6
                return false;
1216
            }
1217
        }
1218
1219 1
        return true;
1220
    }
1221
1222
    /**
1223
     * Returns true if the string contains only hexadecimal chars, false otherwise.
1224
     *
1225
     * @return bool
1226
     *              <p>Whether or not $str contains only hexadecimal chars.</p>
1227
     */
1228 26
    public function isHexadecimal(): bool
1229
    {
1230 26
        return $this->utf8::is_hexadecimal($this->str);
1231
    }
1232
1233
    /**
1234
     * Returns true if the string contains HTML-Tags, false otherwise.
1235
     *
1236
     * @return bool
1237
     *              <p>Whether or not $str contains HTML-Tags.</p>
1238
     */
1239 1
    public function isHtml(): bool
1240
    {
1241 1
        return $this->utf8::is_html($this->str);
1242
    }
1243
1244
    /**
1245
     * Returns true if the string is JSON, false otherwise. Unlike json_decode
1246
     * in PHP 5.x, this method is consistent with PHP 7 and other JSON parsers,
1247
     * in that an empty string is not considered valid JSON.
1248
     *
1249
     * @param bool $onlyArrayOrObjectResultsAreValid
1250
     *
1251
     * @return bool
1252
     *              <p>Whether or not $str is JSON.</p>
1253
     */
1254 40
    public function isJson($onlyArrayOrObjectResultsAreValid = false): bool
1255
    {
1256 40
        return $this->utf8::is_json($this->str, $onlyArrayOrObjectResultsAreValid);
1257
    }
1258
1259
    /**
1260
     * Returns true if the string contains only lower case chars, false otherwise.
1261
     *
1262
     * @return bool
1263
     *              <p>Whether or not $str contains only lower case characters.</p>
1264
     */
1265 16
    public function isLowerCase(): bool
1266
    {
1267 16
        return $this->utf8::is_lowercase($this->str);
1268
    }
1269
1270
    /**
1271
     * Determine whether the string is considered to be NOT empty.
1272
     *
1273
     * A variable is considered NOT empty if it does exist or if its value equals TRUE.
1274
     *
1275
     * @return bool
1276
     *              <p>Whether or not $str is empty().</p>
1277
     */
1278 5
    public function isNotEmpty(): bool
1279
    {
1280 5
        return !$this->utf8::is_empty($this->str);
1281
    }
1282
1283
    /**
1284
     * Returns true if the string is serialized, false otherwise.
1285
     *
1286
     * @return bool
1287
     *              <p>Whether or not $str is serialized.</p>
1288
     */
1289 14
    public function isSerialized(): bool
1290
    {
1291 14
        return $this->utf8::is_serialized($this->str);
1292
    }
1293
1294
    /**
1295
     * Returns true if the string contains only lower case chars, false
1296
     * otherwise.
1297
     *
1298
     * @return bool
1299
     *              <p>Whether or not $str contains only lower case characters.</p>
1300
     */
1301 16
    public function isUpperCase(): bool
1302
    {
1303 16
        return $this->utf8::is_uppercase($this->str);
1304
    }
1305
1306
    /**
1307
     * Returns value which can be serialized by json_encode().
1308
     *
1309
     * @noinspection ReturnTypeCanBeDeclaredInspection
1310
     *
1311
     * @return string The current value of the $str property
1312
     */
1313 1
    public function jsonSerialize()
1314
    {
1315 1
        return (string) $this;
1316
    }
1317
1318
    /**
1319
     * Returns the last $n characters of the string.
1320
     *
1321
     * @param int $n <p>Number of characters to retrieve from the end.</p>
1322
     *
1323
     * @return static
1324
     *                <p>Object with its $str being the last $n chars.</p>
1325
     */
1326 24
    public function last(int $n): self
1327
    {
1328 24
        return static::create(
1329 24
            $this->utf8::str_last_char(
1330 24
                $this->str,
1331 24
                $n,
1332 24
                $this->encoding
1333
            ),
1334 24
            $this->encoding
1335
        );
1336
    }
1337
1338
    /**
1339
     * Gets the substring after (or before via "$beforeNeedle") the last occurrence of the "$needle".
1340
     * If no match is found returns new empty Stringy object.
1341
     *
1342
     * @param string $needle       <p>The string to look for.</p>
1343
     * @param bool   $beforeNeedle [optional] <p>Default: false</p>
1344
     *
1345
     * @return static
1346
     */
1347 2 View Code Duplication
    public function lastSubstringOf(string $needle, bool $beforeNeedle = false): self
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...
1348
    {
1349 2
        return static::create(
1350 2
            $this->utf8::str_substr_last(
1351 2
                $this->str,
1352 2
                $needle,
1353 2
                $beforeNeedle,
1354 2
                $this->encoding
1355
            ),
1356 2
            $this->encoding
1357
        );
1358
    }
1359
1360
    /**
1361
     * Gets the substring after (or before via "$beforeNeedle") the last occurrence of the "$needle".
1362
     * If no match is found returns new empty Stringy object.
1363
     *
1364
     * @param string $needle       <p>The string to look for.</p>
1365
     * @param bool   $beforeNeedle [optional] <p>Default: false</p>
1366
     *
1367
     * @return static
1368
     */
1369 1 View Code Duplication
    public function lastSubstringOfIgnoreCase(string $needle, bool $beforeNeedle = false): self
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...
1370
    {
1371 1
        return static::create(
1372 1
            $this->utf8::str_isubstr_last(
1373 1
                $this->str,
1374 1
                $needle,
1375 1
                $beforeNeedle,
1376 1
                $this->encoding
1377
            ),
1378 1
            $this->encoding
1379
        );
1380
    }
1381
1382
    /**
1383
     * Returns the length of the string.
1384
     *
1385
     * @return int
1386
     *             <p>The number of characters in $str given the encoding.</p>
1387
     */
1388 11
    public function length(): int
1389
    {
1390 11
        return (int) $this->utf8::strlen($this->str, $this->encoding);
1391
    }
1392
1393
    /**
1394
     * Line-Wrap the string after $limit, but also after the next word.
1395
     *
1396
     * @param int $limit
1397
     *
1398
     * @return static
1399
     */
1400 1
    public function lineWrapAfterWord(int $limit): self
1401
    {
1402 1
        return static::create(
1403 1
            $this->utf8::wordwrap_per_line($this->str, $limit),
1404 1
            $this->encoding
1405
        );
1406
    }
1407
1408
    /**
1409
     * Splits on newlines and carriage returns, returning an array of Stringy
1410
     * objects corresponding to the lines in the string.
1411
     *
1412
     * @return CollectionStringy|static[]
1413
     *                                    <p>An collection of Stringy objects.</p>
1414
     */
1415 34
    public function lines(): CollectionStringy
1416
    {
1417 34
        $array = $this->utf8::str_to_lines($this->str);
1418 34
        foreach ($array as $i => &$value) {
1419 34
            $value = static::create($value, $this->encoding);
1420
        }
1421
1422 34
        return CollectionStringy::create($array);
1423
    }
1424
1425
    /**
1426
     * Returns the longest common prefix between the string and $otherStr.
1427
     *
1428
     * @param string $otherStr <p>Second string for comparison.</p>
1429
     *
1430
     * @return static
1431
     *                <p>Object with its $str being the longest common prefix.</p>
1432
     */
1433 20
    public function longestCommonPrefix(string $otherStr): self
1434
    {
1435 20
        return static::create(
1436 20
            $this->utf8::str_longest_common_prefix(
1437 20
                $this->str,
1438 20
                $otherStr,
1439 20
                $this->encoding
1440
            ),
1441 20
            $this->encoding
1442
        );
1443
    }
1444
1445
    /**
1446
     * Returns the longest common substring between the string and $otherStr.
1447
     * In the case of ties, it returns that which occurs first.
1448
     *
1449
     * @param string $otherStr <p>Second string for comparison.</p>
1450
     *
1451
     * @return static
1452
     *                <p>Object with its $str being the longest common substring.</p>
1453
     */
1454 20
    public function longestCommonSubstring(string $otherStr): self
1455
    {
1456 20
        return static::create(
1457 20
            $this->utf8::str_longest_common_substring(
1458 20
                $this->str,
1459 20
                $otherStr,
1460 20
                $this->encoding
1461
            ),
1462 20
            $this->encoding
1463
        );
1464
    }
1465
1466
    /**
1467
     * Returns the longest common suffix between the string and $otherStr.
1468
     *
1469
     * @param string $otherStr <p>Second string for comparison.</p>
1470
     *
1471
     * @return static
1472
     *                <p>Object with its $str being the longest common suffix.</p>
1473
     */
1474 20
    public function longestCommonSuffix(string $otherStr): self
1475
    {
1476 20
        return static::create(
1477 20
            $this->utf8::str_longest_common_suffix(
1478 20
                $this->str,
1479 20
                $otherStr,
1480 20
                $this->encoding
1481
            ),
1482 20
            $this->encoding
1483
        );
1484
    }
1485
1486
    /**
1487
     * Converts the first character of the string to lower case.
1488
     *
1489
     * @return static
1490
     *                <p>Object with the first character of $str being lower case.</p>
1491
     */
1492 10
    public function lowerCaseFirst(): self
1493
    {
1494 10
        return static::create(
1495 10
            $this->utf8::lcfirst($this->str, $this->encoding),
1496 10
            $this->encoding
1497
        );
1498
    }
1499
1500
    /**
1501
     * Returns whether or not a character exists at an index. Offsets may be
1502
     * negative to count from the last character in the string. Implements
1503
     * part of the ArrayAccess interface.
1504
     *
1505
     * @param int $offset <p>The index to check.</p>
1506
     *
1507
     * @return bool
1508
     *              <p>Whether or not the index exists.</p>
1509
     */
1510 12
    public function offsetExists($offset): bool
1511
    {
1512 12
        return $this->utf8::str_offset_exists(
1513 12
            $this->str,
1514 12
            $offset,
1515 12
            $this->encoding
1516
        );
1517
    }
1518
1519
    /**
1520
     * Returns the character at the given index. Offsets may be negative to
1521
     * count from the last character in the string. Implements part of the
1522
     * ArrayAccess interface, and throws an OutOfBoundsException if the index
1523
     * does not exist.
1524
     *
1525
     * @param int $offset <p>The <strong>index</strong> from which to retrieve the char.</p>
1526
     *
1527
     * @throws \OutOfBoundsException
1528
     *                               <p>If the positive or negative offset does not exist.</p>
1529
     *
1530
     * @return string
1531
     *                <p>The character at the specified index.</p>
1532
     */
1533 4
    public function offsetGet($offset): string
1534
    {
1535 4
        return $this->utf8::str_offset_get($this->str, $offset, $this->encoding);
1536
    }
1537
1538
    /**
1539
     * Implements part of the ArrayAccess interface, but throws an exception
1540
     * when called. This maintains the immutability of Stringy objects.
1541
     *
1542
     * @param int   $offset <p>The index of the character.</p>
1543
     * @param mixed $value  <p>Value to set.</p>
1544
     *
1545
     * @throws \Exception
1546
     *                    <p>When called.</p>
1547
     */
1548 2
    public function offsetSet($offset, $value)
1549
    {
1550
        // Stringy is immutable, cannot directly set char
1551
        /** @noinspection ThrowRawExceptionInspection */
1552 2
        throw new \Exception('Stringy object is immutable, cannot modify char');
1553
    }
1554
1555
    /**
1556
     * Implements part of the ArrayAccess interface, but throws an exception
1557
     * when called. This maintains the immutability of Stringy objects.
1558
     *
1559
     * @param int $offset <p>The index of the character.</p>
1560
     *
1561
     * @throws \Exception
1562
     *                    <p>When called.</p>
1563
     */
1564 2
    public function offsetUnset($offset)
1565
    {
1566
        // Don't allow directly modifying the string
1567
        /** @noinspection ThrowRawExceptionInspection */
1568 2
        throw new \Exception('Stringy object is immutable, cannot unset char');
1569
    }
1570
1571
    /**
1572
     * Pads the string to a given length with $padStr. If length is less than
1573
     * or equal to the length of the string, no padding takes places. The
1574
     * default string used for padding is a space, and the default type (one of
1575
     * 'left', 'right', 'both') is 'right'. Throws an InvalidArgumentException
1576
     * if $padType isn't one of those 3 values.
1577
     *
1578
     * @param int    $length  <p>Desired string length after padding.</p>
1579
     * @param string $padStr  [optional] <p>String used to pad, defaults to space. Default: ' '</p>
1580
     * @param string $padType [optional] <p>One of 'left', 'right', 'both'. Default: 'right'</p>
1581
     *
1582
     * @throws \InvalidArgumentException
1583
     *                                   <p>If $padType isn't one of 'right', 'left' or 'both'.</p>
1584
     *
1585
     * @return static
1586
     *                <p>Object with a padded $str.</p>
1587
     */
1588 26
    public function pad(int $length, string $padStr = ' ', string $padType = 'right'): self
1589
    {
1590 26
        return static::create(
1591 26
            $this->utf8::str_pad(
1592 26
                $this->str,
1593 26
                $length,
1594 26
                $padStr,
1595 26
                $padType,
1596 26
                $this->encoding
1597
            )
1598
        );
1599
    }
1600
1601
    /**
1602
     * Returns a new string of a given length such that both sides of the
1603
     * string are padded. Alias for pad() with a $padType of 'both'.
1604
     *
1605
     * @param int    $length <p>Desired string length after padding.</p>
1606
     * @param string $padStr [optional] <p>String used to pad, defaults to space. Default: ' '</p>
1607
     *
1608
     * @return static
1609
     *                <p>String with padding applied.</p>
1610
     */
1611 22
    public function padBoth(int $length, string $padStr = ' '): self
1612
    {
1613 22
        return static::create(
1614 22
            $this->utf8::str_pad_both(
1615 22
                $this->str,
1616 22
                $length,
1617 22
                $padStr,
1618 22
                $this->encoding
1619
            )
1620
        );
1621
    }
1622
1623
    /**
1624
     * Returns a new string of a given length such that the beginning of the
1625
     * string is padded. Alias for pad() with a $padType of 'left'.
1626
     *
1627
     * @param int    $length <p>Desired string length after padding.</p>
1628
     * @param string $padStr [optional] <p>String used to pad, defaults to space. Default: ' '</p>
1629
     *
1630
     * @return static
1631
     *                <p>String with left padding.</p>
1632
     */
1633 14
    public function padLeft(int $length, string $padStr = ' '): self
1634
    {
1635 14
        return static::create(
1636 14
            $this->utf8::str_pad_left(
1637 14
                $this->str,
1638 14
                $length,
1639 14
                $padStr,
1640 14
                $this->encoding
1641
            )
1642
        );
1643
    }
1644
1645
    /**
1646
     * Returns a new string of a given length such that the end of the string
1647
     * is padded. Alias for pad() with a $padType of 'right'.
1648
     *
1649
     * @param int    $length <p>Desired string length after padding.</p>
1650
     * @param string $padStr [optional] <p>String used to pad, defaults to space. Default: ' '</p>
1651
     *
1652
     * @return static
1653
     *                <p>String with right padding.</p>
1654
     */
1655 14
    public function padRight(int $length, string $padStr = ' '): self
1656
    {
1657 14
        return static::create(
1658 14
            $this->utf8::str_pad_right(
1659 14
                $this->str,
1660 14
                $length,
1661 14
                $padStr,
1662 14
                $this->encoding
1663
            )
1664
        );
1665
    }
1666
1667
    /**
1668
     * Returns a new string starting with $string.
1669
     *
1670
     * @param string ...$prefix <p>The string to append.</p>
1671
     *
1672
     * @return static
1673
     *                <p>Object with appended $string.</p>
1674
     *
1675
     * @noinspection PhpDocSignatureInspection
1676
     */
1677 4 View Code Duplication
    public function prepend(string ...$prefix): self
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...
1678
    {
1679 4
        if (\count($prefix) <= 1) {
1680
            /** @noinspection CallableParameterUseCaseInTypeContextInspection */
1681 4
            $prefix = $prefix[0];
1682
        } else {
1683
            /** @noinspection CallableParameterUseCaseInTypeContextInspection */
1684
            $prefix = \implode('', ...$prefix);
1685
        }
1686
1687 4
        return static::create($prefix . $this->str, $this->encoding);
1688
    }
1689
1690
    /**
1691
     * Replaces all occurrences of $pattern in $str by $replacement.
1692
     *
1693
     * @param string $pattern     <p>The regular expression pattern.</p>
1694
     * @param string $replacement <p>The string to replace with.</p>
1695
     * @param string $options     [optional] <p>Matching conditions to be used.</p>
1696
     * @param string $delimiter   [optional] <p>Delimiter the the regex. Default: '/'</p>
1697
     *
1698
     * @return static
1699
     *                <p>Object with the result2ing $str after the replacements.</p>
1700
     */
1701 19
    public function regexReplace(string $pattern, string $replacement, string $options = '', string $delimiter = '/'): self
1702
    {
1703 19
        return static::create(
1704 19
            $this->utf8::regex_replace(
1705 19
                $this->str,
1706 19
                $pattern,
1707 19
                $replacement,
1708 19
                $options,
1709 19
                $delimiter
1710
            ),
1711 19
            $this->encoding
1712
        );
1713
    }
1714
1715
    /**
1716
     * Remove html via "strip_tags()" from the string.
1717
     *
1718
     * @param string $allowableTags [optional] <p>You can use the optional second parameter to specify tags which should
1719
     *                              not be stripped. Default: null
1720
     *                              </p>
1721
     *
1722
     * @return static
1723
     */
1724 6
    public function removeHtml(string $allowableTags = ''): self
1725
    {
1726 6
        return static::create(
1727 6
            $this->utf8::remove_html($this->str, $allowableTags),
1728 6
            $this->encoding
1729
        );
1730
    }
1731
1732
    /**
1733
     * Remove all breaks [<br> | \r\n | \r | \n | ...] from the string.
1734
     *
1735
     * @param string $replacement [optional] <p>Default is a empty string.</p>
1736
     *
1737
     * @return static
1738
     */
1739 6
    public function removeHtmlBreak(string $replacement = ''): self
1740
    {
1741 6
        return static::create(
1742 6
            $this->utf8::remove_html_breaks($this->str, $replacement),
1743 6
            $this->encoding
1744
        );
1745
    }
1746
1747
    /**
1748
     * Returns a new string with the prefix $substring removed, if present.
1749
     *
1750
     * @param string $substring <p>The prefix to remove.</p>
1751
     *
1752
     * @return static
1753
     *                <p>Object having a $str without the prefix $substring.</p>
1754
     */
1755 24
    public function removeLeft(string $substring): self
1756
    {
1757 24
        return static::create(
1758 24
            $this->utf8::remove_left($this->str, $substring, $this->encoding),
1759 24
            $this->encoding
1760
        );
1761
    }
1762
1763
    /**
1764
     * Returns a new string with the suffix $substring removed, if present.
1765
     *
1766
     * @param string $substring <p>The suffix to remove.</p>
1767
     *
1768
     * @return static
1769
     *                <p>Object having a $str without the suffix $substring.</p>
1770
     */
1771 24
    public function removeRight(string $substring): self
1772
    {
1773 24
        return static::create(
1774 24
            $this->utf8::remove_right($this->str, $substring, $this->encoding),
1775 24
            $this->encoding
1776
        );
1777
    }
1778
1779
    /**
1780
     * Try to remove all XSS-attacks from the string.
1781
     *
1782
     * @return static
1783
     */
1784 6
    public function removeXss(): self
1785
    {
1786 6
        static $antiXss = null;
1787
1788 6
        if ($antiXss === null) {
1789 1
            $antiXss = new AntiXSS();
1790
        }
1791
1792 6
        $str = $antiXss->xss_clean($this->str);
1793
1794 6
        return static::create($str, $this->encoding);
1795
    }
1796
1797
    /**
1798
     * Returns a repeated string given a multiplier.
1799
     *
1800
     * @param int $multiplier <p>The number of times to repeat the string.</p>
1801
     *
1802
     * @return static
1803
     *                <p>Object with a repeated str.</p>
1804
     */
1805 14
    public function repeat(int $multiplier): self
1806
    {
1807 14
        return static::create(
1808 14
            \str_repeat($this->str, $multiplier),
1809 14
            $this->encoding
1810
        );
1811
    }
1812
1813
    /**
1814
     * Replaces all occurrences of $search in $str by $replacement.
1815
     *
1816
     * @param string $search        <p>The needle to search for.</p>
1817
     * @param string $replacement   <p>The string to replace with.</p>
1818
     * @param bool   $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
1819
     *
1820
     * @return static
1821
     *                <p>Object with the resulting $str after the replacements.</p>
1822
     */
1823 45
    public function replace(string $search, string $replacement, bool $caseSensitive = true): self
1824
    {
1825 45
        if ($search === '' && $replacement === '') {
1826 10
            return static::create($this->str, $this->encoding);
1827
        }
1828
1829 35
        if ($this->str === '' && $search === '') {
1830 2
            return static::create($replacement, $this->encoding);
1831
        }
1832
1833 33
        if ($caseSensitive) {
1834 28
            return static::create(
1835 28
                $this->utf8::str_replace($search, $replacement, $this->str),
1836 28
                $this->encoding
1837
            );
1838
        }
1839
1840 5
        return static::create(
1841 5
            $this->utf8::str_ireplace($search, $replacement, $this->str),
1842 5
            $this->encoding
1843
        );
1844
    }
1845
1846
    /**
1847
     * Replaces all occurrences of $search in $str by $replacement.
1848
     *
1849
     * @param array        $search        <p>The elements to search for.</p>
1850
     * @param array|string $replacement   <p>The string to replace with.</p>
1851
     * @param bool         $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
1852
     *
1853
     * @return static
1854
     *                <p>Object with the resulting $str after the replacements.</p>
1855
     */
1856 30
    public function replaceAll(array $search, $replacement, bool $caseSensitive = true): self
1857
    {
1858 30
        if ($caseSensitive) {
1859 23
            return static::create(
1860 23
                $this->utf8::str_replace($search, $replacement, $this->str),
1861 23
                $this->encoding
1862
            );
1863
        }
1864
1865 7
        return static::create(
1866 7
            $this->utf8::str_ireplace($search, $replacement, $this->str),
1867 7
            $this->encoding
1868
        );
1869
    }
1870
1871
    /**
1872
     * Replaces all occurrences of $search from the beginning of string with $replacement.
1873
     *
1874
     * @param string $search      <p>The string to search for.</p>
1875
     * @param string $replacement <p>The replacement.</p>
1876
     *
1877
     * @return static
1878
     *                <p>Object with the resulting $str after the replacements.</p>
1879
     */
1880 16
    public function replaceBeginning(string $search, string $replacement): self
1881
    {
1882 16
        return static::create(
1883 16
            $this->utf8::str_replace_beginning($this->str, $search, $replacement),
1884 16
            $this->encoding
1885
        );
1886
    }
1887
1888
    /**
1889
     * Replaces all occurrences of $search from the ending of string with $replacement.
1890
     *
1891
     * @param string $search      <p>The string to search for.</p>
1892
     * @param string $replacement <p>The replacement.</p>
1893
     *
1894
     * @return static
1895
     *                <p>Object with the resulting $str after the replacements.</p>
1896
     */
1897 16
    public function replaceEnding(string $search, string $replacement): self
1898
    {
1899 16
        return static::create(
1900 16
            $this->utf8::str_replace_ending($this->str, $search, $replacement),
1901 16
            $this->encoding
1902
        );
1903
    }
1904
1905
    /**
1906
     * Replaces first occurrences of $search from the beginning of string with $replacement.
1907
     *
1908
     * @param string $search      <p>The string to search for.</p>
1909
     * @param string $replacement <p>The replacement.</p>
1910
     *
1911
     * @return static
1912
     *                <p>Object with the resulting $str after the replacements.</p>
1913
     */
1914 16
    public function replaceFirst(string $search, string $replacement): self
1915
    {
1916 16
        return static::create(
1917 16
            $this->utf8::str_replace_first($search, $replacement, $this->str),
1918 16
            $this->encoding
1919
        );
1920
    }
1921
1922
    /**
1923
     * Replaces last occurrences of $search from the ending of string with $replacement.
1924
     *
1925
     * @param string $search      <p>The string to search for.</p>
1926
     * @param string $replacement <p>The replacement.</p>
1927
     *
1928
     * @return static
1929
     *                <p>Object with the resulting $str after the replacements.</p>
1930
     */
1931 15
    public function replaceLast(string $search, string $replacement): self
1932
    {
1933 15
        return static::create(
1934 15
            $this->utf8::str_replace_last($search, $replacement, $this->str),
1935 15
            $this->encoding
1936
        );
1937
    }
1938
1939
    /**
1940
     * Returns a reversed string. A multibyte version of strrev().
1941
     *
1942
     * @return static
1943
     *                <p>Object with a reversed $str.</p>
1944
     */
1945 10
    public function reverse(): self
1946
    {
1947 10
        return static::create($this->utf8::strrev($this->str), $this->encoding);
1948
    }
1949
1950
    /**
1951
     * Truncates the string to a given length, while ensuring that it does not
1952
     * split words. If $substring is provided, and truncating occurs, the
1953
     * string is further truncated so that the substring may be appended without
1954
     * exceeding the desired length.
1955
     *
1956
     * @param int    $length                          <p>Desired length of the truncated string.</p>
1957
     * @param string $substring                       [optional] <p>The substring to append if it can fit. Default: ''</p>
1958
     * @param bool   $ignoreDoNotSplitWordsForOneWord
1959
     *
1960
     * @return static
1961
     *                <p>Object with the resulting $str after truncating.</p>
1962
     */
1963 45
    public function safeTruncate(int $length, string $substring = '', bool $ignoreDoNotSplitWordsForOneWord = true): self
1964
    {
1965 45
        return static::create(
1966 45
            $this->utf8::str_truncate_safe(
1967 45
                $this->str,
1968 45
                $length,
1969 45
                $substring,
1970 45
                $this->encoding,
1971 45
                $ignoreDoNotSplitWordsForOneWord
1972
            ),
1973 45
            $this->encoding
1974
        );
1975
    }
1976
1977
    /**
1978
     * Shorten the string after $length, but also after the next word.
1979
     *
1980
     * @param int    $length
1981
     * @param string $strAddOn [optional] <p>Default: '…'</p>
1982
     *
1983
     * @return static
1984
     */
1985 4
    public function shortenAfterWord(int $length, string $strAddOn = '…'): self
1986
    {
1987 4
        return static::create(
1988 4
            $this->utf8::str_limit_after_word($this->str, $length, $strAddOn),
1989 4
            $this->encoding
1990
        );
1991
    }
1992
1993
    /**
1994
     * A multibyte string shuffle function. It returns a string with its
1995
     * characters in random order.
1996
     *
1997
     * @return static
1998
     *                <p>Object with a shuffled $str.</p>
1999
     */
2000 6
    public function shuffle(): self
2001
    {
2002 6
        return static::create($this->utf8::str_shuffle($this->str), $this->encoding);
2003
    }
2004
2005
    /**
2006
     * Returns the substring beginning at $start, and up to, but not including
2007
     * the index specified by $end. If $end is omitted, the function extracts
2008
     * the remaining string. If $end is negative, it is computed from the end
2009
     * of the string.
2010
     *
2011
     * @param int $start <p>Initial index from which to begin extraction.</p>
2012
     * @param int $end   [optional] <p>Index at which to end extraction. Default: null</p>
2013
     *
2014
     * @return static
2015
     *                <p>Object with its $str being the extracted substring.</p>
2016
     */
2017 34
    public function slice(int $start, int $end = null): self
2018
    {
2019 34
        return static::create(
2020 34
            $this->utf8::str_slice($this->str, $start, $end, $this->encoding),
2021 34
            $this->encoding
2022
        );
2023
    }
2024
2025
    /**
2026
     * Converts the string into an URL slug. This includes replacing non-ASCII
2027
     * characters with their closest ASCII equivalents, removing remaining
2028
     * non-ASCII and non-alphanumeric characters, and replacing whitespace with
2029
     * $separator. The separator defaults to a single dash, and the string
2030
     * is also converted to lowercase. The language of the source string can
2031
     * also be supplied for language-specific transliteration.
2032
     *
2033
     * @param string                $separator             [optional] <p>The string used to replace whitespace.</p>
2034
     * @param string                $language              [optional] <p>Language of the source string.</p>
2035
     * @param array<string, string> $replacements          [optional] <p>A map of replaceable strings.</p>
2036
     * @param bool                  $replace_extra_symbols [optional]  <p>Add some more replacements e.g. "£" with "
2037
     *                                                     pound ".</p>
2038
     * @param bool                  $use_str_to_lower      [optional] <p>Use "string to lower" for the input.</p>
2039
     * @param bool                  $use_transliterate     [optional]  <p>Use ASCII::to_transliterate() for unknown
2040
     *                                                     chars.</p>
2041
     *
2042
     * @return static
2043
     *                <p>Object whose $str has been converted to an URL slug.</p>
2044
     */
2045 17
    public function slugify(
2046
        string $separator = '-',
2047
        string $language = 'en',
2048
        array $replacements = [],
2049
        bool $replace_extra_symbols = true,
2050
        bool $use_str_to_lower = true,
2051
        bool $use_transliterate = false
2052
    ): self {
2053 17
        return static::create(
2054 17
            $this->ascii::to_slugify(
2055 17
                $this->str,
2056 17
                $separator,
2057 17
                $language,
2058 17
                $replacements,
2059 17
                $replace_extra_symbols,
2060 17
                $use_str_to_lower,
2061 17
                $use_transliterate
2062
            ),
2063 17
            $this->encoding
2064
        );
2065
    }
2066
2067
    /**
2068
     * Convert a string to e.g.: "snake_case"
2069
     *
2070
     * @return static
2071
     *                <p>Object with $str in snake_case.</p>
2072
     */
2073 20
    public function snakeize(): self
2074
    {
2075 20
        return static::create(
2076 20
            $this->utf8::str_snakeize($this->str, $this->encoding),
2077 20
            $this->encoding
2078
        );
2079
    }
2080
2081
    /**
2082
     * Splits the string with the provided regular expression, returning an
2083
     * array of Stringy objects. An optional integer $limit will truncate the
2084
     * results.
2085
     *
2086
     * @param string $pattern <p>The regex with which to split the string.</p>
2087
     * @param int    $limit   [optional] <p>Maximum number of results to return. Default: -1 === no limit</p>
2088
     *
2089
     * @return CollectionStringy|static[]
2090
     *                                    <p>An collection of Stringy objects.</p>
2091
     */
2092 35
    public function split(string $pattern, int $limit = null): CollectionStringy
2093
    {
2094 35
        if ($limit === null) {
2095 7
            $limit = -1;
2096
        }
2097
2098 35
        $array = $this->utf8::str_split_pattern($this->str, $pattern, $limit);
2099 35
        foreach ($array as $i => &$value) {
2100 31
            $value = static::create($value, $this->encoding);
2101
        }
2102
2103 35
        return CollectionStringy::create($array);
2104
    }
2105
2106
    /**
2107
     * Returns true if the string begins with $substring, false otherwise. By
2108
     * default, the comparison is case-sensitive, but can be made insensitive
2109
     * by setting $caseSensitive to false.
2110
     *
2111
     * @param string $substring     <p>The substring to look for.</p>
2112
     * @param bool   $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
2113
     *
2114
     * @return bool
2115
     *              <p>Whether or not $str starts with $substring.</p>
2116
     */
2117 55
    public function startsWith(string $substring, bool $caseSensitive = true): bool
2118
    {
2119 55
        if ($caseSensitive) {
2120 30
            return $this->utf8::str_starts_with($this->str, $substring);
2121
        }
2122
2123 25
        return $this->utf8::str_istarts_with($this->str, $substring);
2124
    }
2125
2126
    /**
2127
     * Returns true if the string begins with any of $substrings, false otherwise.
2128
     * By default the comparison is case-sensitive, but can be made insensitive by
2129
     * setting $caseSensitive to false.
2130
     *
2131
     * @param array $substrings    <p>Substrings to look for.</p>
2132
     * @param bool  $caseSensitive [optional] <p>Whether or not to enforce case-sensitivity. Default: true</p>
2133
     *
2134
     * @return bool
2135
     *              <p>Whether or not $str starts with $substring.</p>
2136
     */
2137 23
    public function startsWithAny(array $substrings, bool $caseSensitive = true): bool
2138
    {
2139 23
        if ($caseSensitive) {
2140 15
            return $this->utf8::str_starts_with_any($this->str, $substrings);
2141
        }
2142
2143 8
        return $this->utf8::str_istarts_with_any($this->str, $substrings);
2144
    }
2145
2146
    /**
2147
     * Strip all whitespace characters. This includes tabs and newline characters,
2148
     * as well as multibyte whitespace such as the thin space and ideographic space.
2149
     *
2150
     * @return static
2151
     */
2152 24
    public function stripWhitespace(): self
2153
    {
2154 24
        return static::create(
2155 24
            $this->utf8::strip_whitespace($this->str),
2156 24
            $this->encoding
2157
        );
2158
    }
2159
2160
    /**
2161
     * Remove css media-queries.
2162
     *
2163
     * @return static
2164
     */
2165 1
    public function stripeCssMediaQueries(): self
2166
    {
2167 1
        return static::create(
2168 1
            $this->utf8::css_stripe_media_queries($this->str),
2169 1
            $this->encoding
2170
        );
2171
    }
2172
2173
    /**
2174
     * Remove empty html-tag.
2175
     *
2176
     * e.g.: <tag></tag>
2177
     *
2178
     * @return static
2179
     */
2180 1
    public function stripeEmptyHtmlTags(): self
2181
    {
2182 1
        return static::create(
2183 1
            $this->utf8::html_stripe_empty_tags($this->str),
2184 1
            $this->encoding
2185
        );
2186
    }
2187
2188
    /**
2189
     * Returns the substring beginning at $start with the specified $length.
2190
     * It differs from the $this->utf8::substr() function in that providing a $length of
2191
     * null will return the rest of the string, rather than an empty string.
2192
     *
2193
     * @param int $start  <p>Position of the first character to use.</p>
2194
     * @param int $length [optional] <p>Maximum number of characters used. Default: null</p>
2195
     *
2196
     * @return static
2197
     *                <p>Object with its $str being the substring.</p>
2198
     */
2199 18
    public function substr(int $start, int $length = null): self
2200
    {
2201 18
        return static::create(
2202 18
            $this->utf8::substr(
2203 18
                $this->str,
2204 18
                $start,
2205 18
                $length,
2206 18
                $this->encoding
2207
            ),
2208 18
            $this->encoding
2209
        );
2210
    }
2211
2212
    /**
2213
     * Gets the substring after (or before via "$beforeNeedle") the first occurrence of the "$needle".
2214
     * If no match is found returns new empty Stringy object.
2215
     *
2216
     * @param string $needle       <p>The string to look for.</p>
2217
     * @param bool   $beforeNeedle [optional] <p>Default: false</p>
2218
     *
2219
     * @return static
2220
     */
2221 2 View Code Duplication
    public function substringOf(string $needle, bool $beforeNeedle = false): self
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...
2222
    {
2223 2
        return static::create(
2224 2
            $this->utf8::str_substr_first(
2225 2
                $this->str,
2226 2
                $needle,
2227 2
                $beforeNeedle,
2228 2
                $this->encoding
2229
            ),
2230 2
            $this->encoding
2231
        );
2232
    }
2233
2234
    /**
2235
     * Gets the substring after (or before via "$beforeNeedle") the first occurrence of the "$needle".
2236
     * If no match is found returns new empty Stringy object.
2237
     *
2238
     * @param string $needle       <p>The string to look for.</p>
2239
     * @param bool   $beforeNeedle [optional] <p>Default: false</p>
2240
     *
2241
     * @return static
2242
     */
2243 2 View Code Duplication
    public function substringOfIgnoreCase(string $needle, bool $beforeNeedle = false): self
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...
2244
    {
2245 2
        return static::create(
2246 2
            $this->utf8::str_isubstr_first(
2247 2
                $this->str,
2248 2
                $needle,
2249 2
                $beforeNeedle,
2250 2
                $this->encoding
2251
            ),
2252 2
            $this->encoding
2253
        );
2254
    }
2255
2256
    /**
2257
     * Surrounds $str with the given substring.
2258
     *
2259
     * @param string $substring <p>The substring to add to both sides.</P>
2260
     *
2261
     * @return static
2262
     *                <p>Object whose $str had the substring both prepended and appended.</p>
2263
     */
2264 10
    public function surround(string $substring): self
2265
    {
2266 10
        return static::create(
2267 10
            $substring . $this->str . $substring,
2268 10
            $this->encoding
2269
        );
2270
    }
2271
2272
    /**
2273
     * Returns a case swapped version of the string.
2274
     *
2275
     * @return static
2276
     *                <p>Object whose $str has each character's case swapped.</P>
2277
     */
2278 10
    public function swapCase(): self
2279
    {
2280 10
        return static::create(
2281 10
            $this->utf8::swapCase($this->str, $this->encoding),
2282 10
            $this->encoding
2283
        );
2284
    }
2285
2286
    /**
2287
     * Returns a string with smart quotes, ellipsis characters, and dashes from
2288
     * Windows-1252 (commonly used in Word documents) replaced by their ASCII
2289
     * equivalents.
2290
     *
2291
     * @return static
2292
     *                <p>Object whose $str has those characters removed.</p>
2293
     */
2294 8
    public function tidy(): self
2295
    {
2296 8
        return static::create(
2297 8
            $this->ascii::normalize_msword($this->str),
2298 8
            $this->encoding
2299
        );
2300
    }
2301
2302
    /**
2303
     * Returns a trimmed string with the first letter of each word capitalized.
2304
     * Also accepts an array, $ignore, allowing you to list words not to be
2305
     * capitalized.
2306
     *
2307
     * @param array|string[]|null $ignore            [optional] <p>An array of words not to capitalize or null.
2308
     *                                               Default: null</p>
2309
     * @param string|null         $word_define_chars [optional] <p>An string of chars that will be used as whitespace
2310
     *                                               separator === words.</p>
2311
     * @param string|null         $language          [optional] <p>Language of the source string.</p>
2312
     *
2313
     * @return static
2314
     *                <p>Object with a titleized $str.</p>
2315
     */
2316 14
    public function titleize(
2317
        array $ignore = null,
2318
        string $word_define_chars = null,
2319
        string $language = null
2320
    ): self {
2321 14
        return static::create(
2322 14
            $this->utf8::str_titleize(
2323 14
                $this->str,
2324 14
                $ignore,
2325 14
                $this->encoding,
2326 14
                false,
2327 14
                $language,
2328 14
                false,
2329 14
                true,
2330 14
                $word_define_chars
2331
            ),
2332 14
            $this->encoding
2333
        );
2334
    }
2335
2336
    /**
2337
     * Returns a trimmed string in proper title case.
2338
     *
2339
     * Also accepts an array, $ignore, allowing you to list words not to be
2340
     * capitalized.
2341
     *
2342
     * Adapted from John Gruber's script.
2343
     *
2344
     * @see https://gist.github.com/gruber/9f9e8650d68b13ce4d78
2345
     *
2346
     * @param array $ignore <p>An array of words not to capitalize.</p>
2347
     *
2348
     * @return static
2349
     *                <p>Object with a titleized $str</p>
2350
     */
2351 35
    public function titleizeForHumans(array $ignore = []): self
2352
    {
2353 35
        return static::create(
2354 35
            $this->utf8::str_titleize_for_humans(
2355 35
                $this->str,
2356 35
                $ignore,
2357 35
                $this->encoding
2358
            ),
2359 35
            $this->encoding
2360
        );
2361
    }
2362
2363
    /**
2364
     * Returns an ASCII version of the string. A set of non-ASCII characters are
2365
     * replaced with their closest ASCII counterparts, and the rest are removed
2366
     * by default. The language or locale of the source string can be supplied
2367
     * for language-specific transliteration in any of the following formats:
2368
     * en, en_GB, or en-GB. For example, passing "de" results in "äöü" mapping
2369
     * to "aeoeue" rather than "aou" as in other languages.
2370
     *
2371
     * @param string $language          [optional] <p>Language of the source string.</p>
2372
     * @param bool   $removeUnsupported [optional] <p>Whether or not to remove the
2373
     *                                  unsupported characters.</p>
2374
     *
2375
     * @return static
2376
     *                <p>Object whose $str contains only ASCII characters.</p>
2377
     */
2378 23
    public function toAscii(string $language = 'en', bool $removeUnsupported = true): self
2379
    {
2380 23
        return static::create(
2381 23
            $this->ascii::to_ascii(
2382 23
                $this->str,
2383 23
                $language,
2384 23
                $removeUnsupported
2385
            ),
2386 23
            $this->encoding
2387
        );
2388
    }
2389
2390
    /**
2391
     * Returns a boolean representation of the given logical string value.
2392
     * For example, 'true', '1', 'on' and 'yes' will return true. 'false', '0',
2393
     * 'off', and 'no' will return false. In all instances, case is ignored.
2394
     * For other numeric strings, their sign will determine the return value.
2395
     * In addition, blank strings consisting of only whitespace will return
2396
     * false. For all other strings, the return value is a result of a
2397
     * boolean cast.
2398
     *
2399
     * @return bool
2400
     *              <p>A boolean value for the string.</p>
2401
     */
2402 30
    public function toBoolean(): bool
2403
    {
2404 30
        return $this->utf8::to_boolean($this->str);
2405
    }
2406
2407
    /**
2408
     * Converts all characters in the string to lowercase.
2409
     *
2410
     * @param bool        $tryToKeepStringLength [optional] <p>true === try to keep the string length: e.g. ẞ -> ß</p>
2411
     * @param string|null $lang                  [optional] <p>Set the language for special cases: az, el, lt, tr</p>
2412
     *
2413
     * @return static
2414
     *                <p>Object with all characters of $str being lowercase.</p>
2415
     */
2416 12 View Code Duplication
    public function toLowerCase($tryToKeepStringLength = false, $lang = null): self
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...
2417
    {
2418 12
        return static::create(
2419 12
            $this->utf8::strtolower(
2420 12
                $this->str,
2421 12
                $this->encoding,
2422 12
                false,
2423 12
                $lang,
2424 12
                $tryToKeepStringLength
2425
            ),
2426 12
            $this->encoding
2427
        );
2428
    }
2429
2430
    /**
2431
     * Converts each tab in the string to some number of spaces, as defined by
2432
     * $tabLength. By default, each tab is converted to 4 consecutive spaces.
2433
     *
2434
     * @param int $tabLength [optional] <p>Number of spaces to replace each tab with. Default: 4</p>
2435
     *
2436
     * @return static
2437
     *                <p>Object whose $str has had tabs switched to spaces.</p>
2438
     */
2439 12 View Code Duplication
    public function toSpaces(int $tabLength = 4): self
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...
2440
    {
2441 12
        if ($tabLength === 4) {
2442 6
            $tab = '    ';
2443 6
        } elseif ($tabLength === 2) {
2444 2
            $tab = '  ';
2445
        } else {
2446 4
            $tab = \str_repeat(' ', $tabLength);
2447
        }
2448
2449 12
        return static::create(
2450 12
            \str_replace("\t", $tab, $this->str),
2451 12
            $this->encoding
2452
        );
2453
    }
2454
2455
    /**
2456
     * Return Stringy object as string, but you can also use (string) for automatically casting the object into a
2457
     * string.
2458
     *
2459
     * @return string
2460
     */
2461 1084
    public function toString(): string
2462
    {
2463 1084
        return (string) $this->str;
2464
    }
2465
2466
    /**
2467
     * Converts each occurrence of some consecutive number of spaces, as
2468
     * defined by $tabLength, to a tab. By default, each 4 consecutive spaces
2469
     * are converted to a tab.
2470
     *
2471
     * @param int $tabLength [optional] <p>Number of spaces to replace with a tab. Default: 4</p>
2472
     *
2473
     * @return static
2474
     *                <p>Object whose $str has had spaces switched to tabs.</p>
2475
     */
2476 10 View Code Duplication
    public function toTabs(int $tabLength = 4): self
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...
2477
    {
2478 10
        if ($tabLength === 4) {
2479 6
            $tab = '    ';
2480 4
        } elseif ($tabLength === 2) {
2481 2
            $tab = '  ';
2482
        } else {
2483 2
            $tab = \str_repeat(' ', $tabLength);
2484
        }
2485
2486 10
        return static::create(
2487 10
            \str_replace($tab, "\t", $this->str),
2488 10
            $this->encoding
2489
        );
2490
    }
2491
2492
    /**
2493
     * Converts the first character of each word in the string to uppercase
2494
     * and all other chars to lowercase.
2495
     *
2496
     * @return static
2497
     *                <p>Object with all characters of $str being title-cased.</p>
2498
     */
2499 10
    public function toTitleCase(): self
2500
    {
2501 10
        return static::create(
2502 10
            $this->utf8::titlecase($this->str, $this->encoding),
2503 10
            $this->encoding
2504
        );
2505
    }
2506
2507
    /**
2508
     * Returns an ASCII version of the string. A set of non-ASCII characters are
2509
     * replaced with their closest ASCII counterparts, and the rest are removed
2510
     * unless instructed otherwise.
2511
     *
2512
     * @param bool   $strict  [optional] <p>Use "transliterator_transliterate()" from PHP-Intl | WARNING: bad
2513
     *                        performance | Default: false</p>
2514
     * @param string $unknown [optional] <p>Character use if character unknown. (default is ?)</p>
2515
     *
2516
     * @return static
2517
     *                <p>Object whose $str contains only ASCII characters.</p>
2518
     */
2519 17
    public function toTransliterate(bool $strict = false, string $unknown = '?'): self
2520
    {
2521 17
        return static::create(
2522 17
            $this->ascii::to_transliterate($this->str, $unknown, $strict),
2523 17
            $this->encoding
2524
        );
2525
    }
2526
2527
    /**
2528
     * Converts all characters in the string to uppercase.
2529
     *
2530
     * @param bool        $tryToKeepStringLength [optional] <p>true === try to keep the string length: e.g. ẞ -> ß</p>
2531
     * @param string|null $lang                  [optional] <p>Set the language for special cases: az, el, lt, tr</p>
2532
     *
2533
     * @return static
2534
     *                <p>Object with all characters of $str being uppercase.</p>
2535
     */
2536 11 View Code Duplication
    public function toUpperCase($tryToKeepStringLength = false, $lang = null): self
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...
2537
    {
2538 11
        return static::create(
2539 11
            $this->utf8::strtoupper($this->str, $this->encoding, false, $lang, $tryToKeepStringLength),
2540 11
            $this->encoding
2541
        );
2542
    }
2543
2544
    /**
2545
     * Returns a string with whitespace removed from the start and end of the
2546
     * string. Supports the removal of unicode whitespace. Accepts an optional
2547
     * string of characters to strip instead of the defaults.
2548
     *
2549
     * @param string $chars [optional] <p>String of characters to strip. Default: null</p>
2550
     *
2551
     * @return static
2552
     *                <p>Object with a trimmed $str.</p>
2553
     */
2554 24
    public function trim(string $chars = null): self
2555
    {
2556 24
        return static::create(
2557 24
            $this->utf8::trim($this->str, $chars),
2558 24
            $this->encoding
2559
        );
2560
    }
2561
2562
    /**
2563
     * Returns a string with whitespace removed from the start of the string.
2564
     * Supports the removal of unicode whitespace. Accepts an optional
2565
     * string of characters to strip instead of the defaults.
2566
     *
2567
     * @param string $chars [optional] <p>Optional string of characters to strip. Default: null</p>
2568
     *
2569
     * @return static
2570
     *                <p>Object with a trimmed $str.</p>
2571
     */
2572 26
    public function trimLeft(string $chars = null): self
2573
    {
2574 26
        return static::create(
2575 26
            $this->utf8::ltrim($this->str, $chars),
2576 26
            $this->encoding
2577
        );
2578
    }
2579
2580
    /**
2581
     * Returns a string with whitespace removed from the end of the string.
2582
     * Supports the removal of unicode whitespace. Accepts an optional
2583
     * string of characters to strip instead of the defaults.
2584
     *
2585
     * @param string $chars [optional] <p>Optional string of characters to strip. Default: null</p>
2586
     *
2587
     * @return static
2588
     *                <p>Object with a trimmed $str.</p>
2589
     */
2590 26
    public function trimRight(string $chars = null): self
2591
    {
2592 26
        return static::create(
2593 26
            $this->utf8::rtrim($this->str, $chars),
2594 26
            $this->encoding
2595
        );
2596
    }
2597
2598
    /**
2599
     * Truncates the string to a given length. If $substring is provided, and
2600
     * truncating occurs, the string is further truncated so that the substring
2601
     * may be appended without exceeding the desired length.
2602
     *
2603
     * @param int    $length    <p>Desired length of the truncated string.</p>
2604
     * @param string $substring [optional] <p>The substring to append if it can fit. Default: ''</p>
2605
     *
2606
     * @return static
2607
     *                <p>Object with the resulting $str after truncating.</p>
2608
     */
2609 44
    public function truncate(int $length, string $substring = ''): self
2610
    {
2611 44
        return static::create(
2612 44
            $this->utf8::str_truncate($this->str, $length, $substring, $this->encoding),
2613 44
            $this->encoding
2614
        );
2615
    }
2616
2617
    /**
2618
     * Returns a lowercase and trimmed string separated by underscores.
2619
     * Underscores are inserted before uppercase characters (with the exception
2620
     * of the first character of the string), and in place of spaces as well as
2621
     * dashes.
2622
     *
2623
     * @return static
2624
     *                <p>Object with an underscored $str.</p>
2625
     */
2626 32
    public function underscored(): self
2627
    {
2628 32
        return $this->delimit('_');
2629
    }
2630
2631
    /**
2632
     * Returns an UpperCamelCase version of the supplied string. It trims
2633
     * surrounding spaces, capitalizes letters following digits, spaces, dashes
2634
     * and underscores, and removes spaces, dashes, underscores.
2635
     *
2636
     * @return static
2637
     *                <p>Object with $str in UpperCamelCase.</p>
2638
     */
2639 26
    public function upperCamelize(): self
2640
    {
2641 26
        return static::create(
2642 26
            $this->utf8::str_upper_camelize($this->str, $this->encoding),
2643 26
            $this->encoding
2644
        );
2645
    }
2646
2647
    /**
2648
     * Converts the first character of the supplied string to upper case.
2649
     *
2650
     * @return static
2651
     *                <p>Object with the first character of $str being upper case.</p>
2652
     */
2653 12
    public function upperCaseFirst(): self
2654
    {
2655 12
        return static::create($this->utf8::ucfirst($this->str, $this->encoding), $this->encoding);
2656
    }
2657
2658
    /**
2659
     * Converts the string into an URL slug. This includes replacing non-ASCII
2660
     * characters with their closest ASCII equivalents, removing remaining
2661
     * non-ASCII and non-alphanumeric characters, and replacing whitespace with
2662
     * $separator. The separator defaults to a single dash, and the string
2663
     * is also converted to lowercase.
2664
     *
2665
     * @param string                $separator    [optional] <p>The string used to replace whitespace. Default: '-'</p>
2666
     * @param string                $language     [optional] <p>The language for the url. Default: 'en'</p>
2667
     * @param array<string, string> $replacements [optional] <p>A map of replaceable strings.</p>
2668
     * @param bool                  $strToLower   [optional] <p>string to lower. Default: true</p>
2669
     *
2670
     * @return static
2671
     *                <p>Object whose $str has been converted to an URL slug.</p>
2672
     */
2673 16
    public function urlify(
2674
        string $separator = '-',
2675
        string $language = 'en',
2676
        array $replacements = [],
2677
        bool $strToLower = true
2678
    ): self {
2679
        // init
2680 16
        $str = $this->str;
2681
2682 16
        foreach ($replacements as $from => $to) {
2683 16
            $str = \str_replace($from, $to, $str);
2684
        }
2685
2686 16
        return static::create(
2687 16
            URLify::slug(
2688 16
                $str,
2689 16
                $language,
2690 16
                $separator,
2691 16
                $strToLower
2692
            ),
2693 16
            $this->encoding
2694
        );
2695
    }
2696
2697
    /**
2698
     * Converts the string into an valid UTF-8 string.
2699
     *
2700
     * @return static
2701
     */
2702 1
    public function utf8ify(): self
2703
    {
2704 1
        return static::create($this->utf8::cleanup($this->str), $this->encoding);
2705
    }
2706
2707
    /**
2708
     * Convert a string into an array of words.
2709
     *
2710
     * @param string   $char_list           <p>Additional chars for the definition of "words".</p>
2711
     * @param bool     $remove_empty_values <p>Remove empty values.</p>
2712
     * @param int|null $remove_short_values <p>The min. string length or null to disable</p>
2713
     *
2714
     * @return CollectionStringy|static[]
2715
     */
2716 1
    public function words(
2717
        string $char_list = '',
2718
        bool $remove_empty_values = false,
2719
        int $remove_short_values = null
2720
    ): CollectionStringy {
2721 1
        return CollectionStringy::createFromStrings(
2722 1
            $this->utf8::str_to_words(
2723 1
                $this->str,
2724 1
                $char_list,
2725 1
                $remove_empty_values,
2726 1
                $remove_short_values
2727
            )
2728
        );
2729
    }
2730
2731
    /**
2732
     * Surrounds $str with the given substring.
2733
     *
2734
     * @param string $substring <p>The substring to add to both sides.</P>
2735
     *
2736
     * @return static
2737
     *                <p>Object whose $str had the substring both prepended and appended.</p>
2738
     */
2739 5
    public function wrap(string $substring): self
2740
    {
2741 5
        return $this->surround($substring);
2742
    }
2743
2744
    /**
2745
     * Returns the replacements for the toAscii() method.
2746
     *
2747
     * @noinspection PhpUnused
2748
     *
2749
     * @return array<string, array<int, string>>
0 ignored issues
show
Documentation introduced by
The doc-type array<string, could not be parsed: Expected ">" at position 5, but found "end of type". (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...
2750
     *                       <p>An array of replacements.</p>
2751
     *
2752
     * @deprecated   this is only here for backward-compatibly reasons
2753
     */
2754 1
    protected function charsArray(): array
2755
    {
2756 1
        return $this->ascii::charsArrayWithMultiLanguageValues();
2757
    }
2758
2759
    /**
2760
     * Returns true if $str matches the supplied pattern, false otherwise.
2761
     *
2762
     * @param string $pattern <p>Regex pattern to match against.</p>
2763
     *
2764
     * @return bool
2765
     *              <p>Whether or not $str matches the pattern.</p>
2766
     */
2767 12
    protected function matchesPattern(string $pattern): bool
2768
    {
2769 12
        return $this->utf8::str_matches_pattern($this->str, $pattern);
2770
    }
2771
}
2772