diff --git a/README.md b/README.md index 8acc65a..0258191 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,8 @@ PHP 5.3+ and HHVM. Inspired by underscore.string.js. * [htmlDecode](#htmldecode) * [htmlEncode](#htmlencode) * [humanize](#humanize) + * [indexOf](#indexof) + * [indexOfLast](#indexoflast) * [insert](#insert) * [isAlpha](#isalpha) * [isAlphanumeric](#isalphanumeric) @@ -475,6 +477,34 @@ S::create('author_id')->humanize(); S::humanize('author_id'); // 'Author' ``` +#### indexOf + +$stringy->indexOf(string $substr [, $offset = 0 ]); + +S::indexOf(string $str , string $substr [, $offset = 0 [, $encoding = null ]]) + +Returns the offset/index of the first occurrence of $substr in the string. +In case $substr is not a substring of the string, returns false. + +```php +S::create('string', 'UTF-8')->indexOf('ing'); +S::indexOf('string', 'ing', 0, 'UTF-8'); // 3 +``` + +#### indexOfLast + +$stringy->indexOfLast(string $substr [, $offset = 0 ]); + +S::indexOfLast(string $str , string $substr [, $offset = 0 [, $encoding = null ]]) + +Returns the offset/index of the last occurrence of $substr in the string. +In case $substr is not a substring of the string, returns false. + +```php +S::create('string', 'UTF-8')->indexOfLast('ing'); +S::indexOfLast('string string', 'ing', 0, 'UTF-8'); // 10 +``` + #### insert $stringy->insert(int $index, string $substring) diff --git a/src/StaticStringy.php b/src/StaticStringy.php index 0462395..d9ac76a 100644 --- a/src/StaticStringy.php +++ b/src/StaticStringy.php @@ -421,6 +421,34 @@ class StaticStringy ->containsAll($needles, $caseSensitive); } + /** + * Returns the offset/index of the first occurance of $substr in the string. + * In case $substr is not a substring of the string, returns false. + * + * @param string $str The haystack to search through + * @param string $substr substring + * @param int $offset + * @return int|bool + */ + public static function indexOf($str, $substr, $offset = 0, $encoding = null) + { + return Stringy::create($str, $encoding)->indexOf($substr, $offset); + } + + /** + * Returns the offset/index of the last occurance of $substr in the string. + * In case $substr is not a substring of the string, returns false. + * + * @param string $str The haystack to search through + * @param string $substr substring + * @param int $offset + * @return int|bool + */ + public static function indexOfLast($str, $substr, $offset = 0, $encoding = null) + { + return Stringy::create($str, $encoding)->indexOfLast($substr, $offset); + } + /** * Surrounds a string with the given substring. * diff --git a/src/Stringy.php b/src/Stringy.php index 23e9cd9..8a03bf4 100644 --- a/src/Stringy.php +++ b/src/Stringy.php @@ -894,6 +894,32 @@ class Stringy implements \Countable, \IteratorAggregate, \ArrayAccess return true; } + /** + * Returns the offset/index of the first occurrence of $substr in the string. + * In case $substr is not a substring of the string, returns false. + * + * @param string $substr substring + * @param int $offset + * @return int|bool + */ + public function indexOf($substr, $offset = 0) + { + return mb_strpos($this->str, (string)$substr, (int)$offset, $this->encoding); + } + + /** + * Returns the offset/index of the last occurrence of $substr in the string. + * In case $substr is not a substring of the string, returns false. + * + * @param string $substr substring + * @param int $offset + * @return int|bool + */ + public function indexOfLast($substr, $offset = 0) + { + return mb_strrpos($this->str, (string)$substr, (int)$offset, $this->encoding); + } + /** * Surrounds $str with the given substring. * diff --git a/tests/CommonTest.php b/tests/CommonTest.php index aa08026..de1d523 100644 --- a/tests/CommonTest.php +++ b/tests/CommonTest.php @@ -14,6 +14,26 @@ abstract class CommonTest extends PHPUnit_Framework_TestCase $this->assertInstanceOf('Stringy\Stringy', $actual); } + public function indexOfProvider() + { + return array( + array(2, 'This is the string', 'is'), + array(2, 'This is the string', 'is', 0, 'UTF-8'), + array(false, 'This is the string', 'not-found', 0, 'UTF-8'), + array(32, 'This is the string... and there is another thing', 'is', 10, 'UTF-8'), + ); + } + + public function indexOfLastProvider() + { + return array( + array(5, 'This is the string', 'is'), + array(5, 'This is the string', 'is', 0, 'UTF-8'), + array(false, 'This is the string', 'not-found', 0, 'UTF-8'), + array(32, 'This is the string... and there is another thing', 'is', 0, 'UTF-8'), + ); + } + public function charsProvider() { return array( diff --git a/tests/StaticStringyTest.php b/tests/StaticStringyTest.php index f029bb2..c093219 100644 --- a/tests/StaticStringyTest.php +++ b/tests/StaticStringyTest.php @@ -6,6 +6,24 @@ use Stringy\StaticStringy as S; class StaticStringyTestCase extends CommonTest { + /** + * @dataProvider indexOfProvider() + */ + public function testIndexOf($expected, $str, $subStr, $offset = 0, $encoding = null) + { + $result = S::indexOf($str, $subStr, $offset, $encoding); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider indexOfLastProvider() + */ + public function testIndexOfLast($expected, $str, $subStr, $offset = 0, $encoding = null) + { + $result = S::indexOfLast($str, $subStr, $offset, $encoding); + $this->assertEquals($expected, $result); + } + /** * @dataProvider charsProvider() */ diff --git a/tests/StringyTest.php b/tests/StringyTest.php index 4bba637..a9a65b3 100644 --- a/tests/StringyTest.php +++ b/tests/StringyTest.php @@ -153,6 +153,24 @@ class StringyTestCase extends CommonTest unset($stringy[1]); } + /** + * @dataProvider indexOfProvider() + */ + public function testIndexOf($expected, $str, $subStr, $offset = 0, $encoding = null) + { + $result = S::create($str, $encoding)->indexOf($subStr, $offset); + $this->assertEquals($expected, $result); + } + + /** + * @dataProvider indexOfLastProvider() + */ + public function testIndexOfLast($expected, $str, $subStr, $offset = 0, $encoding = null) + { + $result = S::create($str, $encoding)->indexOfLast($subStr, $offset); + $this->assertEquals($expected, $result); + } + /** * @dataProvider charsProvider() */