Skip to content

Commit

Permalink
Merge pull request #20034 from salehhashemi1992/feature/string-helper…
Browse files Browse the repository at this point in the history
…-get-between-

Implement StringHelper::findBetween Method
  • Loading branch information
bizley committed Oct 30, 2023
2 parents fcd9e0a + 3d4e108 commit 6804fbe
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 1 deletion.
3 changes: 2 additions & 1 deletion framework/CHANGELOG.md
Expand Up @@ -13,7 +13,8 @@ Yii Framework 2 Change Log
- Enh #12743: Added new methods `BaseActiveRecord::loadRelations()` and `BaseActiveRecord::loadRelationsFor()` to eager load related models for existing primary model instances (PowerGamer1)
- Enh #20030: Improve performance of handling `ErrorHandler::$memoryReserveSize` (antonshevelev, rob006)
- Enh #20042: Add empty array check to `ActiveQueryTrait::findWith()` (renkas)
- Enh #20032: Added `mask` method for string masking with multibyte support (salehhashemi1992)
- Enh #20032: Added `yii\helpers\BaseStringHelper::mask()` method for string masking with multibyte support (salehhashemi1992)
- Enh #20034: Added `yii\helpers\BaseStringHelper::findBetween()` to retrieve a substring that lies between two strings (salehhashemi1992)


2.0.49.2 October 12, 2023
Expand Down
29 changes: 29 additions & 0 deletions framework/helpers/BaseStringHelper.php
Expand Up @@ -527,4 +527,33 @@ public static function mask($string, $start, $length, $mask = '*') {

return $masked;
}

/**
* Returns the portion of the string that lies between the first occurrence of the start string
* and the last occurrence of the end string after that.
*
* @param string $string The input string.
* @param string $start The string marking the start of the portion to extract.
* @param string $end The string marking the end of the portion to extract.
* @return string|null The portion of the string between the first occurrence of
* start and the last occurrence of end, or null if either start or end cannot be found.
*/
public static function findBetween($string, $start, $end)
{
$startPos = mb_strpos($string, $start);

if ($startPos === false) {
return null;
}

// Cut the string from the start position
$subString = mb_substr($string, $startPos + mb_strlen($start));
$endPos = mb_strrpos($subString, $end);

if ($endPos === false) {
return null;
}

return mb_substr($subString, 0, $endPos);
}
}
30 changes: 30 additions & 0 deletions tests/framework/helpers/StringHelperTest.php
Expand Up @@ -506,4 +506,34 @@ public function testMask()
$this->assertSame('em**l@email.com', StringHelper::mask('email@email.com', 2, 2));
$this->assertSame('******email.com', StringHelper::mask('email@email.com', 0, 6));
}

/**
* @param string $string
* @param string $start
* @param string $end
* @param string $expectedResult
* @dataProvider dataProviderFindBetween
*/
public function testFindBetween($string, $start, $end, $expectedResult)
{
$this->assertSame($expectedResult, StringHelper::findBetween($string, $start, $end));
}

public function dataProviderFindBetween()
{
return [
['hello world hello', ' hello', ' world', null], // end before start
['This is a sample string', ' is ', ' string', 'a sample'], // normal case
['startendstart', 'start', 'end', ''], // end before start
['startmiddleend', 'start', 'end', 'middle'], // normal case
['startend', 'start', 'end', ''], // end immediately follows start
['multiple start start end end', 'start ', ' end', 'start end'], // multiple starts and ends
['', 'start', 'end', null], // empty string
['no delimiters here', 'start', 'end', null], // no start and end
['start only', 'start', 'end', null], // start found but no end
['end only', 'start', 'end', null], // end found but no start
['spécial !@#$%^&*()', 'spé', '&*()', 'cial !@#$%^'], // Special characters
['من صالح هاشمی هستم', 'من ', ' هستم', 'صالح هاشمی'], // other languages
];
}
}

0 comments on commit 6804fbe

Please sign in to comment.