Skip to content

Commit 37db45d

Browse files
[String] Add trimSuffix() and trimPrefix() methods
1 parent 412eda2 commit 37db45d

File tree

4 files changed

+131
-0
lines changed

4 files changed

+131
-0
lines changed

AbstractString.php

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,11 +616,79 @@ abstract public function trim(string $chars = " \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}")
616616
*/
617617
abstract public function trimEnd(string $chars = " \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}"): self;
618618

619+
/**
620+
* @param string|string[] $prefix
621+
*
622+
* @return static
623+
*/
624+
public function trimPrefix($prefix): self
625+
{
626+
if (\is_array($prefix) || $prefix instanceof \Traversable) {
627+
foreach ($prefix as $s) {
628+
$t = $this->trimPrefix($s);
629+
630+
if ($t->string !== $this->string) {
631+
return $t;
632+
}
633+
}
634+
635+
return clone $this;
636+
}
637+
638+
$str = clone $this;
639+
640+
if ($prefix instanceof self) {
641+
$prefix = $prefix->string;
642+
} else {
643+
$prefix = (string) $prefix;
644+
}
645+
646+
if ('' !== $prefix && \strlen($this->string) >= \strlen($prefix) && 0 === substr_compare($this->string, $prefix, 0, \strlen($prefix), $this->ignoreCase)) {
647+
$str->string = substr($this->string, \strlen($prefix));
648+
}
649+
650+
return $str;
651+
}
652+
619653
/**
620654
* @return static
621655
*/
622656
abstract public function trimStart(string $chars = " \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}"): self;
623657

658+
/**
659+
* @param string|string[] $suffix
660+
*
661+
* @return static
662+
*/
663+
public function trimSuffix($suffix): self
664+
{
665+
if (\is_array($suffix) || $suffix instanceof \Traversable) {
666+
foreach ($suffix as $s) {
667+
$t = $this->trimSuffix($s);
668+
669+
if ($t->string !== $this->string) {
670+
return $t;
671+
}
672+
}
673+
674+
return clone $this;
675+
}
676+
677+
$str = clone $this;
678+
679+
if ($suffix instanceof self) {
680+
$suffix = $suffix->string;
681+
} else {
682+
$suffix = (string) $suffix;
683+
}
684+
685+
if ('' !== $suffix && \strlen($this->string) >= \strlen($suffix) && 0 === substr_compare($this->string, $suffix, -\strlen($suffix), null, $this->ignoreCase)) {
686+
$str->string = substr($this->string, 0, -\strlen($suffix));
687+
}
688+
689+
return $str;
690+
}
691+
624692
/**
625693
* @return static
626694
*/

AbstractUnicodeString.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,26 @@ public function trimEnd(string $chars = " \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}"): pare
409409
return $str;
410410
}
411411

412+
public function trimPrefix($prefix): parent
413+
{
414+
if (!$this->ignoreCase) {
415+
return parent::trimPrefix($prefix);
416+
}
417+
418+
$str = clone $this;
419+
420+
if ($prefix instanceof \Traversable) {
421+
$prefix = iterator_to_array($prefix, false);
422+
} elseif ($prefix instanceof parent) {
423+
$prefix = $prefix->string;
424+
}
425+
426+
$prefix = implode('|', array_map('preg_quote', (array) $prefix));
427+
$str->string = preg_replace("{^(?:$prefix)}iuD", '', $this->string);
428+
429+
return $str;
430+
}
431+
412432
public function trimStart(string $chars = " \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}"): parent
413433
{
414434
if (" \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}" !== $chars && !preg_match('//u', $chars)) {
@@ -422,6 +442,26 @@ public function trimStart(string $chars = " \t\n\r\0\x0B\x0C\u{A0}\u{FEFF}"): pa
422442
return $str;
423443
}
424444

445+
public function trimSuffix($suffix): parent
446+
{
447+
if (!$this->ignoreCase) {
448+
return parent::trimSuffix($suffix);
449+
}
450+
451+
$str = clone $this;
452+
453+
if ($suffix instanceof \Traversable) {
454+
$suffix = iterator_to_array($suffix, false);
455+
} elseif ($suffix instanceof parent) {
456+
$suffix = $suffix->string;
457+
}
458+
459+
$suffix = implode('|', array_map('preg_quote', (array) $suffix));
460+
$str->string = preg_replace("{(?:$suffix)$}iuD", '', $this->string);
461+
462+
return $str;
463+
}
464+
425465
public function upper(): parent
426466
{
427467
$str = clone $this;

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
5.4
5+
---
6+
7+
* Add `trimSuffix()` and `trimPrefix()` methods
8+
49
5.3
510
---
611

Tests/AbstractAsciiTestCase.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,15 @@ public static function provideTrim()
733733
];
734734
}
735735

736+
public function testTrimPrefix()
737+
{
738+
$str = static::createFromString('abc.def');
739+
740+
$this->assertEquals(static::createFromString('def'), $str->trimPrefix('abc.'));
741+
$this->assertEquals(static::createFromString('def'), $str->trimPrefix(['abc.', 'def']));
742+
$this->assertEquals(static::createFromString('def'), $str->ignoreCase()->trimPrefix('ABC.'));
743+
}
744+
736745
/**
737746
* @dataProvider provideTrimStart
738747
*/
@@ -744,6 +753,15 @@ public function testTrimStart(string $expected, string $origin, ?string $chars)
744753
$this->assertEquals(static::createFromString($expected), $result);
745754
}
746755

756+
public function testTrimSuffix()
757+
{
758+
$str = static::createFromString('abc.def');
759+
760+
$this->assertEquals(static::createFromString('abc'), $str->trimSuffix('.def'));
761+
$this->assertEquals(static::createFromString('abc'), $str->trimSuffix(['.def', 'abc']));
762+
$this->assertEquals(static::createFromString('abc'), $str->ignoreCase()->trimSuffix('.DEF'));
763+
}
764+
747765
public static function provideTrimStart()
748766
{
749767
return [

0 commit comments

Comments
 (0)