Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement StringHelper::findBetween Method #20034

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion framework/CHANGELOG.md
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
Expand Up @@ -527,4 +527,33 @@

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)

Check warning on line 541 in framework/helpers/BaseStringHelper.php

View check run for this annotation

Codecov / codecov/patch

framework/helpers/BaseStringHelper.php#L541

Added line #L541 was not covered by tests
{
$startPos = mb_strpos($string, $start);

Check warning on line 543 in framework/helpers/BaseStringHelper.php

View check run for this annotation

Codecov / codecov/patch

framework/helpers/BaseStringHelper.php#L543

Added line #L543 was not covered by tests

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

Check warning on line 546 in framework/helpers/BaseStringHelper.php

View check run for this annotation

Codecov / codecov/patch

framework/helpers/BaseStringHelper.php#L545-L546

Added lines #L545 - L546 were not covered by tests
}

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

Check warning on line 551 in framework/helpers/BaseStringHelper.php

View check run for this annotation

Codecov / codecov/patch

framework/helpers/BaseStringHelper.php#L550-L551

Added lines #L550 - L551 were not covered by tests

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

Check warning on line 554 in framework/helpers/BaseStringHelper.php

View check run for this annotation

Codecov / codecov/patch

framework/helpers/BaseStringHelper.php#L553-L554

Added lines #L553 - L554 were not covered by tests
}

return mb_substr($subString, 0, $endPos);

Check warning on line 557 in framework/helpers/BaseStringHelper.php

View check run for this annotation

Codecov / codecov/patch

framework/helpers/BaseStringHelper.php#L557

Added line #L557 was not covered by tests
}
}
30 changes: 30 additions & 0 deletions tests/framework/helpers/StringHelperTest.php
Original file line number Diff line number Diff line change
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
];
}
}
Loading