Skip to content

Commit 20968da

Browse files
committed
feat(str): add replaceLast() method
1 parent 350d6d9 commit 20968da

3 files changed

Lines changed: 66 additions & 0 deletions

File tree

docs/methods.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,19 @@ echo $str->replaceFirst('xyz', 'baz');
685685
// foo bar foo
686686
```
687687

688+
### replaceLast `Utility`
689+
Replace the last occurrence of a value in the string
690+
691+
```php
692+
$str = new Utility('foo bar foo')
693+
694+
echo $str->replaceLast('foo', 'baz');
695+
// foo bar baz
696+
697+
echo $str->replaceLast('xyz', 'baz');
698+
// foo bar foo
699+
```
700+
688701
### reverse `Utility`
689702
Reverse the string
690703

src/Utility.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -714,6 +714,27 @@ public function replaceFirst(string $search, string $replace): Utility
714714
return static::make($before . $replace . $after, $this->encoding);
715715
}
716716

717+
/**
718+
* Replace the last occurrence of a value in the string
719+
*/
720+
public function replaceLast(string $search, string $replace): Utility
721+
{
722+
if ($search === '') {
723+
return static::make($this->string, $this->encoding);
724+
}
725+
726+
$position = mb_strrpos($this->string, $search, 0, $this->encoding);
727+
728+
if ($position === false) {
729+
return static::make($this->string, $this->encoding);
730+
}
731+
732+
$before = mb_substr($this->string, 0, $position, $this->encoding);
733+
$after = mb_substr($this->string, $position + mb_strlen($search, $this->encoding), null, $this->encoding);
734+
735+
return static::make($before . $replace . $after, $this->encoding);
736+
}
737+
717738
/**
718739
* Replace none alpha characters in the string with the given value
719740
*/

tests/ReplaceLastTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Tests;
6+
7+
use PHPUnit\Framework\Attributes\DataProvider;
8+
use Iterator;
9+
10+
final class ReplaceLastTest extends BaseStringSuite
11+
{
12+
public static function __validData(): Iterator
13+
{
14+
yield ['foo bar baz', 'foo bar foo', 'foo', 'baz'];
15+
yield ['Hello World', 'Hello World', 'xyz', 'abc'];
16+
yield ['Hello World', 'Hello World', '', 'abc'];
17+
yield ['Hello World', 'Hello Hello World', 'Hello', ''];
18+
yield ['', '', 'foo', 'bar'];
19+
yield ['foobär', 'foobaz', 'baz', 'bär'];
20+
yield ['foo-bar-baz', 'foo-bar-bar', 'bar', 'baz'];
21+
yield ['fooXX', 'foobar', 'bar', 'XX'];
22+
yield ['foobar', 'foobar', 'BAR', 'XX'];
23+
yield ['a::b::X', 'a::b::c', 'c', 'X'];
24+
yield ['foo.bar.XX', 'foo.bar.baz', 'baz', 'XX'];
25+
}
26+
27+
#[DataProvider('__validData')]
28+
public function testReplaceLastMethod(string $expected, string $string, string $search, string $replace): void
29+
{
30+
$this->assertSame($expected, $this->utility($string)->replaceLast($search, $replace)->value());
31+
}
32+
}

0 commit comments

Comments
 (0)