Skip to content

Commit

Permalink
[10.x] Adds start and end string replacement helpers (#48025)
Browse files Browse the repository at this point in the history
* add start and end replacement helpers

* formatting

---------

Co-authored-by: Taylor Otwell <[email protected]>
  • Loading branch information
joedixon and taylorotwell authored Aug 23, 2023
1 parent b6e4dff commit 38434a7
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 0 deletions.
48 changes: 48 additions & 0 deletions src/Illuminate/Support/Str.php
Original file line number Diff line number Diff line change
Expand Up @@ -1007,6 +1007,29 @@ public static function replaceFirst($search, $replace, $subject)
return $subject;
}

/**
* Replace the first occurrence of the given value if it appears at the start of the string.
*
* @param string $search
* @param string $replace
* @param string $subject
* @return string
*/
public static function replaceStart($search, $replace, $subject)
{
$search = (string) $search;

if ($search === '') {
return $subject;
}

if (static::startsWith($subject, $search)) {
return static::replaceFirst($search, $replace, $subject);
}

return $subject;
}

/**
* Replace the last occurrence of a given value in the string.
*
Expand All @@ -1017,6 +1040,8 @@ public static function replaceFirst($search, $replace, $subject)
*/
public static function replaceLast($search, $replace, $subject)
{
$search = (string) $search;

if ($search === '') {
return $subject;
}
Expand All @@ -1030,6 +1055,29 @@ public static function replaceLast($search, $replace, $subject)
return $subject;
}

/**
* Replace the last occurrence of a given value if it appears at the end of the string.
*
* @param string $search
* @param string $replace
* @param string $subject
* @return string
*/
public static function replaceEnd($search, $replace, $subject)
{
$search = (string) $search;

if ($search === '') {
return $subject;
}

if (static::endsWith($subject, $search)) {
return static::replaceLast($search, $replace, $subject);
}

return $subject;
}

/**
* Remove any occurrence of the given string in the subject.
*
Expand Down
24 changes: 24 additions & 0 deletions src/Illuminate/Support/Stringable.php
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,18 @@ public function replaceFirst($search, $replace)
return new static(Str::replaceFirst($search, $replace, $this->value));
}

/**
* Replace the first occurrence of the given value if it appears at the start of the string.
*
* @param string $search
* @param string $replace
* @return static
*/
public function replaceStart($search, $replace)
{
return new static(Str::replaceStart($search, $replace, $this->value));
}

/**
* Replace the last occurrence of a given value in the string.
*
Expand All @@ -668,6 +680,18 @@ public function replaceLast($search, $replace)
return new static(Str::replaceLast($search, $replace, $this->value));
}

/**
* Replace the last occurrence of a given value if it appears at the end of the string.
*
* @param string $search
* @param string $replace
* @return static
*/
public function replaceEnd($search, $replace)
{
return new static(Str::replaceEnd($search, $replace, $this->value));
}

/**
* Replace the patterns matching the given regular expression.
*
Expand Down
27 changes: 27 additions & 0 deletions tests/Support/SupportStrTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,19 @@ public function testReplaceFirst()
$this->assertSame('Jönköping Malmö', Str::replaceFirst('', 'yyy', 'Jönköping Malmö'));
}

public function testReplaceStart()
{
$this->assertSame('foobar foobar', Str::replaceStart('bar', 'qux', 'foobar foobar'));
$this->assertSame('foo/bar? foo/bar?', Str::replaceStart('bar?', 'qux?', 'foo/bar? foo/bar?'));
$this->assertSame('quxbar foobar', Str::replaceStart('foo', 'qux', 'foobar foobar'));
$this->assertSame('qux? foo/bar?', Str::replaceStart('foo/bar?', 'qux?', 'foo/bar? foo/bar?'));
$this->assertSame('bar foobar', Str::replaceStart('foo', '', 'foobar foobar'));
$this->assertSame('1', Str::replaceStart(0, '1', '0'));
// Test for multibyte string support
$this->assertSame('xxxnköping Malmö', Str::replaceStart('', 'xxx', 'Jönköping Malmö'));
$this->assertSame('Jönköping Malmö', Str::replaceStart('', 'yyy', 'Jönköping Malmö'));
}

public function testReplaceLast()
{
$this->assertSame('foobar fooqux', Str::replaceLast('bar', 'qux', 'foobar foobar'));
Expand All @@ -621,6 +634,20 @@ public function testReplaceLast()
$this->assertSame('Malmö Jönköping', Str::replaceLast('', 'yyy', 'Malmö Jönköping'));
}

public function testReplaceEnd()
{
$this->assertSame('foobar fooqux', Str::replaceEnd('bar', 'qux', 'foobar foobar'));
$this->assertSame('foo/bar? foo/qux?', Str::replaceEnd('bar?', 'qux?', 'foo/bar? foo/bar?'));
$this->assertSame('foobar foo', Str::replaceEnd('bar', '', 'foobar foobar'));
$this->assertSame('foobar foobar', Str::replaceEnd('xxx', 'yyy', 'foobar foobar'));
$this->assertSame('foobar foobar', Str::replaceEnd('', 'yyy', 'foobar foobar'));
$this->assertSame('fooxxx foobar', Str::replaceEnd('xxx', 'yyy', 'fooxxx foobar'));

// // Test for multibyte string support
$this->assertSame('Malmö Jönköping', Str::replaceEnd('ö', 'xxx', 'Malmö Jönköping'));
$this->assertSame('Malmö Jönkyyy', Str::replaceEnd('öping', 'yyy', 'Malmö Jönköping'));
}

public function testRemove()
{
$this->assertSame('Fbar', Str::remove('o', 'Foobar'));
Expand Down
27 changes: 27 additions & 0 deletions tests/Support/SupportStringableTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -863,6 +863,19 @@ public function testReplaceFirst()
$this->assertSame('Jönköping Malmö', (string) $this->stringable('Jönköping Malmö')->replaceFirst('', 'yyy'));
}

public function testReplaceStart()
{
$this->assertSame('foobar foobar', (string) $this->stringable('foobar foobar')->replaceStart('bar', 'qux'));
$this->assertSame('foo/bar? foo/bar?', (string) $this->stringable('foo/bar? foo/bar?')->replaceStart('bar?', 'qux?'));
$this->assertSame('quxbar foobar', (string) $this->stringable('foobar foobar')->replaceStart('foo', 'qux'));
$this->assertSame('qux? foo/bar?', (string) $this->stringable('foo/bar? foo/bar?')->replaceStart('foo/bar?', 'qux?'));
$this->assertSame('bar foobar', (string) $this->stringable('foobar foobar')->replaceStart('foo', ''));
$this->assertSame('1', (string) $this->stringable('0')->replaceStart(0, '1'));
// Test for multibyte string support
$this->assertSame('xxxnköping Malmö', (string) $this->stringable('Jönköping Malmö')->replaceStart('', 'xxx'));
$this->assertSame('Jönköping Malmö', (string) $this->stringable('Jönköping Malmö')->replaceStart('', 'yyy'));
}

public function testReplaceLast()
{
$this->assertSame('foobar fooqux', (string) $this->stringable('foobar foobar')->replaceLast('bar', 'qux'));
Expand All @@ -875,6 +888,20 @@ public function testReplaceLast()
$this->assertSame('Malmö Jönköping', (string) $this->stringable('Malmö Jönköping')->replaceLast('', 'yyy'));
}

public function testReplaceEnd()
{
$this->assertSame('foobar fooqux', (string) $this->stringable('foobar foobar')->replaceEnd('bar', 'qux'));
$this->assertSame('foo/bar? foo/qux?', (string) $this->stringable('foo/bar? foo/bar?')->replaceEnd('bar?', 'qux?'));
$this->assertSame('foobar foo', (string) $this->stringable('foobar foobar')->replaceEnd('bar', ''));
$this->assertSame('foobar foobar', (string) $this->stringable('foobar foobar')->replaceLast('xxx', 'yyy'));
$this->assertSame('foobar foobar', (string) $this->stringable('foobar foobar')->replaceEnd('', 'yyy'));
$this->assertSame('fooxxx foobar', (string) $this->stringable('fooxxx foobar')->replaceEnd('xxx', 'yyy'));

// // Test for multibyte string support
$this->assertSame('Malmö Jönköping', (string) $this->stringable('Malmö Jönköping')->replaceEnd('ö', 'xxx'));
$this->assertSame('Malmö Jönkyyy', (string) $this->stringable('Malmö Jönköping')->replaceEnd('öping', 'yyy'));
}

public function testRemove()
{
$this->assertSame('Fbar', (string) $this->stringable('Foobar')->remove('o'));
Expand Down

0 comments on commit 38434a7

Please sign in to comment.