Skip to content

Commit 38434a7

Browse files
[10.x] Adds start and end string replacement helpers (#48025)
* add start and end replacement helpers * formatting --------- Co-authored-by: Taylor Otwell <taylor@laravel.com>
1 parent b6e4dff commit 38434a7

File tree

4 files changed

+126
-0
lines changed

4 files changed

+126
-0
lines changed

src/Illuminate/Support/Str.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,6 +1007,29 @@ public static function replaceFirst($search, $replace, $subject)
10071007
return $subject;
10081008
}
10091009

1010+
/**
1011+
* Replace the first occurrence of the given value if it appears at the start of the string.
1012+
*
1013+
* @param string $search
1014+
* @param string $replace
1015+
* @param string $subject
1016+
* @return string
1017+
*/
1018+
public static function replaceStart($search, $replace, $subject)
1019+
{
1020+
$search = (string) $search;
1021+
1022+
if ($search === '') {
1023+
return $subject;
1024+
}
1025+
1026+
if (static::startsWith($subject, $search)) {
1027+
return static::replaceFirst($search, $replace, $subject);
1028+
}
1029+
1030+
return $subject;
1031+
}
1032+
10101033
/**
10111034
* Replace the last occurrence of a given value in the string.
10121035
*
@@ -1017,6 +1040,8 @@ public static function replaceFirst($search, $replace, $subject)
10171040
*/
10181041
public static function replaceLast($search, $replace, $subject)
10191042
{
1043+
$search = (string) $search;
1044+
10201045
if ($search === '') {
10211046
return $subject;
10221047
}
@@ -1030,6 +1055,29 @@ public static function replaceLast($search, $replace, $subject)
10301055
return $subject;
10311056
}
10321057

1058+
/**
1059+
* Replace the last occurrence of a given value if it appears at the end of the string.
1060+
*
1061+
* @param string $search
1062+
* @param string $replace
1063+
* @param string $subject
1064+
* @return string
1065+
*/
1066+
public static function replaceEnd($search, $replace, $subject)
1067+
{
1068+
$search = (string) $search;
1069+
1070+
if ($search === '') {
1071+
return $subject;
1072+
}
1073+
1074+
if (static::endsWith($subject, $search)) {
1075+
return static::replaceLast($search, $replace, $subject);
1076+
}
1077+
1078+
return $subject;
1079+
}
1080+
10331081
/**
10341082
* Remove any occurrence of the given string in the subject.
10351083
*

src/Illuminate/Support/Stringable.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,18 @@ public function replaceFirst($search, $replace)
656656
return new static(Str::replaceFirst($search, $replace, $this->value));
657657
}
658658

659+
/**
660+
* Replace the first occurrence of the given value if it appears at the start of the string.
661+
*
662+
* @param string $search
663+
* @param string $replace
664+
* @return static
665+
*/
666+
public function replaceStart($search, $replace)
667+
{
668+
return new static(Str::replaceStart($search, $replace, $this->value));
669+
}
670+
659671
/**
660672
* Replace the last occurrence of a given value in the string.
661673
*
@@ -668,6 +680,18 @@ public function replaceLast($search, $replace)
668680
return new static(Str::replaceLast($search, $replace, $this->value));
669681
}
670682

683+
/**
684+
* Replace the last occurrence of a given value if it appears at the end of the string.
685+
*
686+
* @param string $search
687+
* @param string $replace
688+
* @return static
689+
*/
690+
public function replaceEnd($search, $replace)
691+
{
692+
return new static(Str::replaceEnd($search, $replace, $this->value));
693+
}
694+
671695
/**
672696
* Replace the patterns matching the given regular expression.
673697
*

tests/Support/SupportStrTest.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,19 @@ public function testReplaceFirst()
609609
$this->assertSame('Jönköping Malmö', Str::replaceFirst('', 'yyy', 'Jönköping Malmö'));
610610
}
611611

612+
public function testReplaceStart()
613+
{
614+
$this->assertSame('foobar foobar', Str::replaceStart('bar', 'qux', 'foobar foobar'));
615+
$this->assertSame('foo/bar? foo/bar?', Str::replaceStart('bar?', 'qux?', 'foo/bar? foo/bar?'));
616+
$this->assertSame('quxbar foobar', Str::replaceStart('foo', 'qux', 'foobar foobar'));
617+
$this->assertSame('qux? foo/bar?', Str::replaceStart('foo/bar?', 'qux?', 'foo/bar? foo/bar?'));
618+
$this->assertSame('bar foobar', Str::replaceStart('foo', '', 'foobar foobar'));
619+
$this->assertSame('1', Str::replaceStart(0, '1', '0'));
620+
// Test for multibyte string support
621+
$this->assertSame('xxxnköping Malmö', Str::replaceStart('', 'xxx', 'Jönköping Malmö'));
622+
$this->assertSame('Jönköping Malmö', Str::replaceStart('', 'yyy', 'Jönköping Malmö'));
623+
}
624+
612625
public function testReplaceLast()
613626
{
614627
$this->assertSame('foobar fooqux', Str::replaceLast('bar', 'qux', 'foobar foobar'));
@@ -621,6 +634,20 @@ public function testReplaceLast()
621634
$this->assertSame('Malmö Jönköping', Str::replaceLast('', 'yyy', 'Malmö Jönköping'));
622635
}
623636

637+
public function testReplaceEnd()
638+
{
639+
$this->assertSame('foobar fooqux', Str::replaceEnd('bar', 'qux', 'foobar foobar'));
640+
$this->assertSame('foo/bar? foo/qux?', Str::replaceEnd('bar?', 'qux?', 'foo/bar? foo/bar?'));
641+
$this->assertSame('foobar foo', Str::replaceEnd('bar', '', 'foobar foobar'));
642+
$this->assertSame('foobar foobar', Str::replaceEnd('xxx', 'yyy', 'foobar foobar'));
643+
$this->assertSame('foobar foobar', Str::replaceEnd('', 'yyy', 'foobar foobar'));
644+
$this->assertSame('fooxxx foobar', Str::replaceEnd('xxx', 'yyy', 'fooxxx foobar'));
645+
646+
// // Test for multibyte string support
647+
$this->assertSame('Malmö Jönköping', Str::replaceEnd('ö', 'xxx', 'Malmö Jönköping'));
648+
$this->assertSame('Malmö Jönkyyy', Str::replaceEnd('öping', 'yyy', 'Malmö Jönköping'));
649+
}
650+
624651
public function testRemove()
625652
{
626653
$this->assertSame('Fbar', Str::remove('o', 'Foobar'));

tests/Support/SupportStringableTest.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -863,6 +863,19 @@ public function testReplaceFirst()
863863
$this->assertSame('Jönköping Malmö', (string) $this->stringable('Jönköping Malmö')->replaceFirst('', 'yyy'));
864864
}
865865

866+
public function testReplaceStart()
867+
{
868+
$this->assertSame('foobar foobar', (string) $this->stringable('foobar foobar')->replaceStart('bar', 'qux'));
869+
$this->assertSame('foo/bar? foo/bar?', (string) $this->stringable('foo/bar? foo/bar?')->replaceStart('bar?', 'qux?'));
870+
$this->assertSame('quxbar foobar', (string) $this->stringable('foobar foobar')->replaceStart('foo', 'qux'));
871+
$this->assertSame('qux? foo/bar?', (string) $this->stringable('foo/bar? foo/bar?')->replaceStart('foo/bar?', 'qux?'));
872+
$this->assertSame('bar foobar', (string) $this->stringable('foobar foobar')->replaceStart('foo', ''));
873+
$this->assertSame('1', (string) $this->stringable('0')->replaceStart(0, '1'));
874+
// Test for multibyte string support
875+
$this->assertSame('xxxnköping Malmö', (string) $this->stringable('Jönköping Malmö')->replaceStart('', 'xxx'));
876+
$this->assertSame('Jönköping Malmö', (string) $this->stringable('Jönköping Malmö')->replaceStart('', 'yyy'));
877+
}
878+
866879
public function testReplaceLast()
867880
{
868881
$this->assertSame('foobar fooqux', (string) $this->stringable('foobar foobar')->replaceLast('bar', 'qux'));
@@ -875,6 +888,20 @@ public function testReplaceLast()
875888
$this->assertSame('Malmö Jönköping', (string) $this->stringable('Malmö Jönköping')->replaceLast('', 'yyy'));
876889
}
877890

891+
public function testReplaceEnd()
892+
{
893+
$this->assertSame('foobar fooqux', (string) $this->stringable('foobar foobar')->replaceEnd('bar', 'qux'));
894+
$this->assertSame('foo/bar? foo/qux?', (string) $this->stringable('foo/bar? foo/bar?')->replaceEnd('bar?', 'qux?'));
895+
$this->assertSame('foobar foo', (string) $this->stringable('foobar foobar')->replaceEnd('bar', ''));
896+
$this->assertSame('foobar foobar', (string) $this->stringable('foobar foobar')->replaceLast('xxx', 'yyy'));
897+
$this->assertSame('foobar foobar', (string) $this->stringable('foobar foobar')->replaceEnd('', 'yyy'));
898+
$this->assertSame('fooxxx foobar', (string) $this->stringable('fooxxx foobar')->replaceEnd('xxx', 'yyy'));
899+
900+
// // Test for multibyte string support
901+
$this->assertSame('Malmö Jönköping', (string) $this->stringable('Malmö Jönköping')->replaceEnd('ö', 'xxx'));
902+
$this->assertSame('Malmö Jönkyyy', (string) $this->stringable('Malmö Jönköping')->replaceEnd('öping', 'yyy'));
903+
}
904+
878905
public function testRemove()
879906
{
880907
$this->assertSame('Fbar', (string) $this->stringable('Foobar')->remove('o'));

0 commit comments

Comments
 (0)