* @template-implements \ArrayAccess */ class Stringy implements \ArrayAccess, \Countable, \IteratorAggregate, \JsonSerializable { /** * An instance's string. * * @var string */ protected $str; /** * The string's encoding, which should be one of the mbstring module's * supported encodings. * * @var string */ protected $encoding; /** * @var UTF8 */ private $utf8; /** * @var ASCII */ private $ascii; /** * Initializes a Stringy object and assigns both str and encoding properties * the supplied values. $str is cast to a string prior to assignment, and if * $encoding is not specified, it defaults to mb_internal_encoding(). Throws * an InvalidArgumentException if the first argument is an array or object * without a __toString method. * * @param object|scalar $str [optional]

Value to modify, after being cast to string. Default: ''

* @param string $encoding [optional]

The character encoding. Fallback: 'UTF-8'

* * @throws \InvalidArgumentException *

if an array or object without a * __toString method is passed as the first argument

* * @psalm-mutation-free */ public function __construct($str = '', string $encoding = null) { /* @phpstan-ignore-next-line | always false in theory */ if (\is_array($str)) { throw new \InvalidArgumentException( 'Passed value cannot be an array' ); } if ( \is_object($str) && !\method_exists($str, '__toString') ) { throw new \InvalidArgumentException( 'Passed object must have a __toString method' ); } $this->str = (string) $str; static $ASCII = null; if ($ASCII === null) { $ASCII = new ASCII(); } $this->ascii = $ASCII; static $UTF8 = null; if ($UTF8 === null) { $UTF8 = new UTF8(); } $this->utf8 = $UTF8; if ($encoding !== 'UTF-8') { $this->encoding = $this->utf8::normalize_encoding($encoding, 'UTF-8'); } else { $this->encoding = $encoding; } } /** * Returns the value in $str. * * EXAMPLE: * * * @psalm-mutation-free * * @return string *

The current value of the $str property.

*/ public function __toString() { return (string) $this->str; } /** * Return part of the string occurring after a specific string. * * EXAMPLE: * s('宮本 茂')->after('本'); // ' 茂' * * * @param string $string

The delimiting string.

* * @psalm-mutation-free * * @return static */ public function after(string $string): self { $strArray = UTF8::str_split_pattern( $this->str, $string ); unset($strArray[0]); return new static( \implode(' ', $strArray), $this->encoding ); } /** * Gets the substring after the first occurrence of a separator. * If no match is found returns new empty Stringy object. * * EXAMPLE: * s('')->afterFirst('b'); // '>' * * * @param string $separator * * @psalm-mutation-free * * @return static */ public function afterFirst(string $separator): self { return static::create( $this->utf8::str_substr_after_first_separator( $this->str, $separator, $this->encoding ) ); } /** * Gets the substring after the first occurrence of a separator. * If no match is found returns new empty Stringy object. * * EXAMPLE: * s('')->afterFirstIgnoreCase('b'); // '>' * * * @param string $separator * * @psalm-mutation-free * * @return static */ public function afterFirstIgnoreCase(string $separator): self { return static::create( $this->utf8::str_isubstr_after_first_separator( $this->str, $separator, $this->encoding ) ); } /** * Gets the substring after the last occurrence of a separator. * If no match is found returns new empty Stringy object. * * EXAMPLE: * s('')->afterLast('b'); // '>' * * * @param string $separator * * @psalm-mutation-free * * @return static */ public function afterLast(string $separator): self { return static::create( $this->utf8::str_substr_after_last_separator( $this->str, $separator, $this->encoding ) ); } /** * Gets the substring after the last occurrence of a separator. * If no match is found returns new empty Stringy object. * * EXAMPLE: * s('')->afterLastIgnoreCase('b'); // '>' * * * @param string $separator * * @psalm-mutation-free * * @return static */ public function afterLastIgnoreCase(string $separator): self { return static::create( $this->utf8::str_isubstr_after_last_separator( $this->str, $separator, $this->encoding ) ); } /** * Returns a new string with $suffix appended. * * EXAMPLE: * s('fòô')->append('bàř'); // 'fòôbàř' * * * @param string ...$suffix

The string to append.

* * @psalm-mutation-free * * @return static *

Object with appended $suffix.

*/ public function append(string ...$suffix): self { if (\count($suffix) <= 1) { $suffix = $suffix[0]; } else { $suffix = \implode('', $suffix); } return static::create($this->str . $suffix, $this->encoding); } /** * Append an password (limited to chars that are good readable). * * EXAMPLE: * s('')->appendPassword(8); // e.g.: '89bcdfgh' * * * @param int $length

Length of the random string.

* * @return static *

Object with appended password.

*/ public function appendPassword(int $length): self { return $this->appendRandomString( $length, '2346789bcdfghjkmnpqrtvwxyzBCDFGHJKLMNPQRTVWXYZ!?_#' ); } /** * Append an random string. * * EXAMPLE: * s('')->appendUniqueIdentifier(5, 'ABCDEFGHI'); // e.g.: 'CDEHI' * * * @param int $length

Length of the random string.

* @param string $possibleChars [optional]

Characters string for the random selection.

* * @return static *

Object with appended random string.

*/ public function appendRandomString(int $length, string $possibleChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'): self { $str = $this->utf8::get_random_string($length, $possibleChars); return $this->append($str); } /** * Returns a new string with $suffix appended. * * EXAMPLE: * * * @param CollectionStringy|static ...$suffix

The Stringy objects to append.

* * @phpstan-param CollectionStringy|static ...$suffix * * @psalm-mutation-free * * @return static *

Object with appended $suffix.

*/ public function appendStringy(...$suffix): self { $suffixStr = ''; foreach ($suffix as $suffixTmp) { if ($suffixTmp instanceof CollectionStringy) { $suffixStr .= $suffixTmp->implode(''); } else { $suffixStr .= $suffixTmp->toString(); } } return static::create($this->str . $suffixStr, $this->encoding); } /** * Append an unique identifier. * * EXAMPLE: * s('')->appendUniqueIdentifier(); // e.g.: '1f3870be274f6c49b3e31a0c6728957f' * * * @param int|string $entropyExtra [optional]

Extra entropy via a string or int value.

* @param bool $md5 [optional]

Return the unique identifier as md5-hash? Default: true

* * @return static *

Object with appended unique identifier as md5-hash.

*/ public function appendUniqueIdentifier($entropyExtra = '', bool $md5 = true): self { return $this->append( $this->utf8::get_unique_string($entropyExtra, $md5) ); } /** * Returns the character at $index, with indexes starting at 0. * * EXAMPLE: * s('fòôbàř')->at(3); // 'b' * * * @param int $index

Position of the character.

* * @psalm-mutation-free * * @return static *

The character at $index.

*/ public function at(int $index): self { return static::create($this->utf8::char_at($this->str, $index), $this->encoding); } /** * Decode the base64 encoded string. * * EXAMPLE: * * * @psalm-mutation-free * * @return self */ public function base64Decode(): self { return static::create( \base64_decode($this->str, true), $this->encoding ); } /** * Encode the string to base64. * * EXAMPLE: * * * @psalm-mutation-free * * @return self */ public function base64Encode(): self { return static::create( \base64_encode($this->str), $this->encoding ); } /** * Creates a hash from the string using the CRYPT_BLOWFISH algorithm. * * WARNING: Using this algorithm, will result in the ```$this->str``` * being truncated to a maximum length of 72 characters. * * EXAMPLE: * * * @param array $options [optional]

An array of bcrypt hasing options.

* * @psalm-mutation-free * * @return static */ public function bcrypt(array $options = []): self { return new static( \password_hash( $this->str, \PASSWORD_BCRYPT, $options ), $this->encoding ); } /** * Return part of the string occurring before a specific string. * * EXAMPLE: * * * @param string $string

The delimiting string.

* * @psalm-mutation-free * * @return static */ public function before(string $string): self { $strArray = UTF8::str_split_pattern( $this->str, $string, 1 ); return new static( $strArray[0] ?? '', $this->encoding ); } /** * Gets the substring before the first occurrence of a separator. * If no match is found returns new empty Stringy object. * * EXAMPLE: * s('')->beforeFirst('b'); // ' * * @param string $separator * * @psalm-mutation-free * * @return static */ public function beforeFirst(string $separator): self { return static::create( $this->utf8::str_substr_before_first_separator( $this->str, $separator, $this->encoding ) ); } /** * Gets the substring before the first occurrence of a separator. * If no match is found returns new empty Stringy object. * * EXAMPLE: * s('')->beforeFirstIgnoreCase('b'); // ' * * @param string $separator * * @psalm-mutation-free * * @return static */ public function beforeFirstIgnoreCase(string $separator): self { return static::create( $this->utf8::str_isubstr_before_first_separator( $this->str, $separator, $this->encoding ) ); } /** * Gets the substring before the last occurrence of a separator. * If no match is found returns new empty Stringy object. * * EXAMPLE: * s('')->beforeLast('b'); // ' * * @param string $separator * * @psalm-mutation-free * * @return static */ public function beforeLast(string $separator): self { return static::create( $this->utf8::str_substr_before_last_separator( $this->str, $separator, $this->encoding ) ); } /** * Gets the substring before the last occurrence of a separator. * If no match is found returns new empty Stringy object. * * EXAMPLE: * s('')->beforeLastIgnoreCase('b'); // ' * * @param string $separator * * @psalm-mutation-free * * @return static */ public function beforeLastIgnoreCase(string $separator): self { return static::create( $this->utf8::str_isubstr_before_last_separator( $this->str, $separator, $this->encoding ) ); } /** * Returns the substring between $start and $end, if found, or an empty * string. An optional offset may be supplied from which to begin the * search for the start string. * * EXAMPLE: * s('{foo} and {bar}')->between('{', '}'); // 'foo' * * * @param string $start

Delimiter marking the start of the substring.

* @param string $end

Delimiter marking the end of the substring.

* @param int $offset [optional]

Index from which to begin the search. Default: 0

* * @psalm-mutation-free * * @return static *

Object whose $str is a substring between $start and $end.

*/ public function between(string $start, string $end, int $offset = null): self { $str = $this->utf8::between( $this->str, $start, $end, (int) $offset, $this->encoding ); return static::create($str, $this->encoding); } /** * Call a user function. * * EXAMPLE: * S::create('foo bar lall')->callUserFunction(static function ($str) { * return UTF8::str_limit($str, 8); * })->toString(); // "foo bar…" * * * @param callable $function * @param mixed ...$parameter * * @psalm-mutation-free * * @return static *

Object having a $str changed via $function.

*/ public function callUserFunction(callable $function, ...$parameter): self { $str = $function($this->str, ...$parameter); return static::create( $str, $this->encoding ); } /** * Returns a camelCase version of the string. Trims surrounding spaces, * capitalizes letters following digits, spaces, dashes and underscores, * and removes spaces, dashes, as well as underscores. * * EXAMPLE: * s('Camel-Case')->camelize(); // 'camelCase' * * * @psalm-mutation-free * * @return static *

Object with $str in camelCase.

*/ public function camelize(): self { return static::create( $this->utf8::str_camelize($this->str, $this->encoding), $this->encoding ); } /** * Returns the string with the first letter of each word capitalized, * except for when the word is a name which shouldn't be capitalized. * * EXAMPLE: * s('jaap de hoop scheffer')->capitalizePersonName(); // 'Jaap de Hoop Scheffer' * * * @psalm-mutation-free * * @return static *

Object with $str capitalized.

*/ public function capitalizePersonalName(): self { return static::create( $this->utf8::str_capitalize_name($this->str), $this->encoding ); } /** * Returns an array consisting of the characters in the string. * * EXAMPLE: * s('fòôbàř')->chars(); // ['f', 'ò', 'ô', 'b', 'à', 'ř'] * * * @psalm-mutation-free * * @return string[] *

An array of string chars.

*/ public function chars(): array { /** @var string[] */ return $this->utf8::str_split($this->str); } /** * Splits the string into chunks of Stringy objects. * * EXAMPLE: * s('foobar')->chunk(3); // ['foo', 'bar'] * * * @param int $length [optional]

Max character length of each array element.

* * @psalm-mutation-free * * @return static[] *

An array of Stringy objects.

* * @phpstan-return array */ public function chunk(int $length = 1): array { if ($length < 1) { throw new \InvalidArgumentException('The chunk length must be greater than zero.'); } if ($this->str === '') { return []; } $chunks = $this->utf8::str_split($this->str, $length); foreach ($chunks as &$value) { $value = static::create($value, $this->encoding); } /** @noinspection PhpSillyAssignmentInspection */ /** @var static[] $chunks */ $chunks = $chunks; return $chunks; } /** * Splits the string into chunks of Stringy objects collection. * * EXAMPLE: * * * @param int $length [optional]

Max character length of each array element.

* * @psalm-mutation-free * * @return CollectionStringy|static[] *

An collection of Stringy objects.

* * @phpstan-return CollectionStringy */ public function chunkCollection(int $length = 1): CollectionStringy { /** * @psalm-suppress ImpureMethodCall -> add more psalm stuff to the collection class */ return CollectionStringy::create( $this->chunk($length) ); } /** * Trims the string and replaces consecutive whitespace characters with a * single space. This includes tabs and newline characters, as well as * multibyte whitespace such as the thin space and ideographic space. * * EXAMPLE: * s(' Ο συγγραφέας ')->collapseWhitespace(); // 'Ο συγγραφέας' * * * @psalm-mutation-free * * @return static *

Object with a trimmed $str and condensed whitespace.

*/ public function collapseWhitespace(): self { return static::create( $this->utf8::collapse_whitespace($this->str), $this->encoding ); } /** * Returns true if the string contains $needle, false otherwise. By default * the comparison is case-sensitive, but can be made insensitive by setting * $caseSensitive to false. * * EXAMPLE: * s('Ο συγγραφέας είπε')->contains('συγγραφέας'); // true * * * @param string $needle

Substring to look for.

* @param bool $caseSensitive [optional]

Whether or not to enforce case-sensitivity. Default: true

* * @psalm-mutation-free * * @return bool *

Whether or not $str contains $needle.

*/ public function contains(string $needle, bool $caseSensitive = true): bool { return $this->utf8::str_contains( $this->str, $needle, $caseSensitive ); } /** * Returns true if the string contains all $needles, false otherwise. By * default the comparison is case-sensitive, but can be made insensitive by * setting $caseSensitive to false. * * EXAMPLE: * s('foo & bar')->containsAll(['foo', 'bar']); // true * * * @param string[] $needles

SubStrings to look for.

* @param bool $caseSensitive [optional]

Whether or not to enforce case-sensitivity. Default: true

* * @psalm-mutation-free * * @return bool *

Whether or not $str contains $needle.

*/ public function containsAll(array $needles, bool $caseSensitive = true): bool { return $this->utf8::str_contains_all( $this->str, $needles, $caseSensitive ); } /** * Returns true if the string contains any $needles, false otherwise. By * default the comparison is case-sensitive, but can be made insensitive by * setting $caseSensitive to false. * * EXAMPLE: * s('str contains foo')->containsAny(['foo', 'bar']); // true * * * @param string[] $needles

SubStrings to look for.

* @param bool $caseSensitive [optional]

Whether or not to enforce case-sensitivity. Default: true

* * @psalm-mutation-free * * @return bool *

Whether or not $str contains $needle.

*/ public function containsAny(array $needles, bool $caseSensitive = true): bool { return $this->utf8::str_contains_any( $this->str, $needles, $caseSensitive ); } /** * Checks if string starts with "BOM" (Byte Order Mark Character) character. * * EXAMPLE: s("\xef\xbb\xbf foobar")->containsBom(); // true * * @psalm-mutation-free * * @return bool * true if the string has BOM at the start,
* false otherwise */ public function containsBom(): bool { return $this->utf8::string_has_bom($this->str); } /** * Returns the length of the string, implementing the countable interface. * * EXAMPLE: * * * @psalm-mutation-free * * @return int *

The number of characters in the string, given the encoding.

*/ public function count(): int { return $this->length(); } /** * Returns the number of occurrences of $substring in the given string. * By default, the comparison is case-sensitive, but can be made insensitive * by setting $caseSensitive to false. * * EXAMPLE: * s('Ο συγγραφέας είπε')->countSubstr('α'); // 2 * * * @param string $substring

The substring to search for.

* @param bool $caseSensitive [optional]

Whether or not to enforce case-sensitivity. Default: true

* * @psalm-mutation-free * * @return int */ public function countSubstr(string $substring, bool $caseSensitive = true): int { return $this->utf8::substr_count_simple( $this->str, $substring, $caseSensitive, $this->encoding ); } /** * Calculates the crc32 polynomial of a string. * * EXAMPLE: * * * @psalm-mutation-free * * @return int */ public function crc32(): int { return \crc32($this->str); } /** * Creates a Stringy object and assigns both str and encoding properties * the supplied values. $str is cast to a string prior to assignment, and if * $encoding is not specified, it defaults to mb_internal_encoding(). It * then returns the initialized object. Throws an InvalidArgumentException * if the first argument is an array or object without a __toString method. * * @param mixed $str [optional]

Value to modify, after being cast to string. Default: ''

* @param string $encoding [optional]

The character encoding. Fallback: 'UTF-8'

* * @throws \InvalidArgumentException *

if an array or object without a * __toString method is passed as the first argument

* * @return static *

A Stringy object.

* @phpstan-pure */ public static function create($str = '', string $encoding = null): self { return new static($str, $encoding); } /** * One-way string encryption (hashing). * * Hash the string using the standard Unix DES-based algorithm or an * alternative algorithm that may be available on the system. * * PS: if you need encrypt / decrypt, please use ```static::encrypt($password)``` * and ```static::decrypt($password)``` * * EXAMPLE: * * * @param string $salt

A salt string to base the hashing on.

* * @psalm-mutation-free * * @return static */ public function crypt(string $salt): self { return new static( \crypt( $this->str, $salt ), $this->encoding ); } /** * Returns a lowercase and trimmed string separated by dashes. Dashes are * inserted before uppercase characters (with the exception of the first * character of the string), and in place of spaces as well as underscores. * * EXAMPLE: * s('fooBar')->dasherize(); // 'foo-bar' * * * @psalm-mutation-free * * @return static *

Object with a dasherized $str

*/ public function dasherize(): self { return static::create( $this->utf8::str_dasherize($this->str), $this->encoding ); } /** * Decrypt the string. * * EXAMPLE: * * * @param string $password The key for decrypting * * @psalm-mutation-free * * @return static */ public function decrypt(string $password): self { /** * @psalm-suppress ImpureMethodCall -> add more psalm stuff to vendor stuff */ return new static( Crypto::decryptWithPassword($this->str, $password), $this->encoding ); } /** * Returns a lowercase and trimmed string separated by the given delimiter. * Delimiters are inserted before uppercase characters (with the exception * of the first character of the string), and in place of spaces, dashes, * and underscores. Alpha delimiters are not converted to lowercase. * * EXAMPLE: * s('fooBar')->delimit('::'); // 'foo::bar' * * * @param string $delimiter

Sequence used to separate parts of the string.

* * @psalm-mutation-free * * @return static *

Object with a delimited $str.

*/ public function delimit(string $delimiter): self { return static::create( $this->utf8::str_delimit($this->str, $delimiter), $this->encoding ); } /** * Encode the given string into the given $encoding + set the internal character encoding. * * EXAMPLE: * * * @param string $new_encoding

The desired character encoding.

* @param bool $auto_detect_encoding [optional]

Auto-detect the current string-encoding

* * @psalm-mutation-free * * @return static */ public function encode(string $new_encoding, bool $auto_detect_encoding = false): self { if ($auto_detect_encoding) { $str = $this->utf8::encode( $new_encoding, $this->str ); } else { $str = $this->utf8::encode( $new_encoding, $this->str, false, $this->encoding ); } return new static($str, $new_encoding); } /** * Encrypt the string. * * EXAMPLE: * * * @param string $password

The key for encrypting

* * @psalm-mutation-free * * @return static */ public function encrypt(string $password): self { /** * @psalm-suppress ImpureMethodCall -> add more psalm stuff to vendor stuff */ return new static( Crypto::encryptWithPassword($this->str, $password), $this->encoding ); } /** * Returns true if the string ends with $substring, false otherwise. By * default, the comparison is case-sensitive, but can be made insensitive * by setting $caseSensitive to false. * * EXAMPLE: * s('fòôbàř')->endsWith('bàř', true); // true * * * @param string $substring

The substring to look for.

* @param bool $caseSensitive [optional]

Whether or not to enforce case-sensitivity. Default: true

* * @psalm-mutation-free * * @return bool *

Whether or not $str ends with $substring.

*/ public function endsWith(string $substring, bool $caseSensitive = true): bool { if ($caseSensitive) { return $this->utf8::str_ends_with($this->str, $substring); } return $this->utf8::str_iends_with($this->str, $substring); } /** * Returns true if the string ends with any of $substrings, false otherwise. * By default, the comparison is case-sensitive, but can be made insensitive * by setting $caseSensitive to false. * * EXAMPLE: * s('fòôbàř')->endsWithAny(['bàř', 'baz'], true); // true * * * @param string[] $substrings

Substrings to look for.

* @param bool $caseSensitive [optional]

Whether or not to enforce case-sensitivity. Default: true

* * @psalm-mutation-free * * @return bool *

Whether or not $str ends with $substring.

*/ public function endsWithAny(array $substrings, bool $caseSensitive = true): bool { if ($caseSensitive) { return $this->utf8::str_ends_with_any($this->str, $substrings); } return $this->utf8::str_iends_with_any($this->str, $substrings); } /** * Ensures that the string begins with $substring. If it doesn't, it's * prepended. * * EXAMPLE: * s('foobar')->ensureLeft('http://'); // 'http://foobar' * * * @param string $substring

The substring to add if not present.

* * @psalm-mutation-free * * @return static *

Object with its $str prefixed by the $substring.

*/ public function ensureLeft(string $substring): self { return static::create( $this->utf8::str_ensure_left($this->str, $substring), $this->encoding ); } /** * Ensures that the string ends with $substring. If it doesn't, it's appended. * * EXAMPLE: * s('foobar')->ensureRight('.com'); // 'foobar.com' * * * @param string $substring

The substring to add if not present.

* * @psalm-mutation-free * * @return static *

Object with its $str suffixed by the $substring.

*/ public function ensureRight(string $substring): self { return static::create( $this->utf8::str_ensure_right($this->str, $substring), $this->encoding ); } /** * Create a escape html version of the string via "htmlspecialchars()". * * EXAMPLE: * s('<∂∆ onerror="alert(xss)">')->escape(); // '<∂∆ onerror="alert(xss)">' * * * @psalm-mutation-free * * @return static */ public function escape(): self { return static::create( $this->utf8::htmlspecialchars( $this->str, \ENT_QUOTES | \ENT_SUBSTITUTE, $this->encoding ), $this->encoding ); } /** * Split a string by a string. * * EXAMPLE: * * * @param string $delimiter

The boundary string

* @param int $limit [optional]

The maximum number of elements in the exploded * collection.

* * - If limit is set and positive, the returned collection will contain a maximum of limit elements with the last * element containing the rest of string. * - If the limit parameter is negative, all components except the last -limit are returned. * - If the limit parameter is zero, then this is treated as 1 * * @psalm-mutation-free * * @return array */ public function explode(string $delimiter, int $limit = \PHP_INT_MAX): array { if ($this->str === '') { return []; } /** @phpstan-ignore-next-line - FP -> non-empty-string is already checked */ $strings = \explode($delimiter, $this->str, $limit); /** @phpstan-ignore-next-line - if "$delimiter" is an empty string, then "explode()" will return "false" */ if ($strings === false) { $strings = []; } return \array_map( function ($str) { return new static($str, $this->encoding); }, $strings ); } /** * Split a string by a string. * * EXAMPLE: * * * @param string $delimiter

The boundary string

* @param int $limit [optional]

The maximum number of elements in the exploded * collection.

* * - If limit is set and positive, the returned collection will contain a maximum of limit elements with the last * element containing the rest of string. * - If the limit parameter is negative, all components except the last -limit are returned. * - If the limit parameter is zero, then this is treated as 1 * * @psalm-mutation-free * * @return CollectionStringy|static[] *

An collection of Stringy objects.

* * @phpstan-return CollectionStringy */ public function explodeCollection(string $delimiter, int $limit = \PHP_INT_MAX): CollectionStringy { /** * @psalm-suppress ImpureMethodCall -> add more psalm stuff to the collection class */ return CollectionStringy::create( $this->explode($delimiter, $limit) ); } /** * Create an extract from a sentence, so if the search-string was found, it try to centered in the output. * * EXAMPLE: * $sentence = 'This is only a Fork of Stringy, take a look at the new features.'; * s($sentence)->extractText('Stringy'); // '...Fork of Stringy...' * * * @param string $search * @param int|null $length [optional]

Default: null === text->length / 2

* @param string $replacerForSkippedText [optional]

Default: …

* * @psalm-mutation-free * * @return static */ public function extractText(string $search = '', int $length = null, string $replacerForSkippedText = '…'): self { return static::create( $this->utf8::extract_text( $this->str, $search, $length, $replacerForSkippedText, $this->encoding ), $this->encoding ); } /** * Returns the first $n characters of the string. * * EXAMPLE: * s('fòôbàř')->first(3); // 'fòô' * * * @param int $n

Number of characters to retrieve from the start.

* * @psalm-mutation-free * * @return static *

Object with its $str being the first $n chars.

*/ public function first(int $n): self { return static::create( $this->utf8::first_char($this->str, $n, $this->encoding), $this->encoding ); } /** * Return a formatted string via sprintf + named parameters via array syntax. * *

*
* It will use "sprintf()" so you can use e.g.: *
*

s('There are %d monkeys in the %s')->format(5, 'tree');
*
*
s('There are %2$d monkeys in the %1$s')->format('tree', 5);
*
*
* But you can also use named parameter via array syntax e.g.: *
*
s('There are %:count monkeys in the %:location')->format(['count' => 5, 'location' => 'tree');
*

* * EXAMPLE: * $input = 'one: %2$d, %1$s: 2, %:text_three: %3$d'; * s($input)->format(['text_three' => '%4$s'], 'two', 1, 3, 'three'); // 'One: 1, two: 2, three: 3' * * * @param mixed ...$args [optional] * * @psalm-mutation-free * * @return static *

A Stringy object produced according to the formatting string * format.

*/ public function format(...$args): self { // init $str = $this->str; if (\strpos($this->str, '%:') !== false) { $offset = null; $replacement = null; /** @noinspection AlterInForeachInspection */ foreach ($args as $key => &$arg) { if (!\is_array($arg)) { continue; } foreach ($arg as $name => $param) { $name = (string) $name; if (\strpos($name, '%:') !== 0) { $nameTmp = '%:' . $name; } else { $nameTmp = $name; } if ($offset === null) { $offset = \strpos($str, $nameTmp); } else { $offset = \strpos($str, $nameTmp, (int) $offset + \strlen((string) $replacement)); } if ($offset === false) { continue; } unset($arg[$name]); $str = \substr_replace($str, (string) $param, (int) $offset, \strlen($nameTmp)); } unset($args[$key]); } } $str = \str_replace('%:', '%%:', $str); return static::create( \sprintf($str, ...$args), $this->encoding ); } /** * Returns the encoding used by the Stringy object. * * EXAMPLE: * s('fòôbàř', 'UTF-8')->getEncoding(); // 'UTF-8' * * * @psalm-mutation-free * * @return string *

The current value of the $encoding property.

*/ public function getEncoding(): string { return $this->encoding; } /** * Returns a new ArrayIterator, thus implementing the IteratorAggregate * interface. The ArrayIterator's constructor is passed an array of chars * in the multibyte string. This enables the use of foreach with instances * of Stringy\Stringy. * * EXAMPLE: * * * @psalm-mutation-free * * @return \ArrayIterator *

An iterator for the characters in the string.

* * @phpstan-return \ArrayIterator */ public function getIterator(): \ArrayIterator { return new \ArrayIterator($this->chars()); } /** * Wrap the string after an exact number of characters. * * EXAMPLE: * * * @param int $width

Number of characters at which to wrap.

* @param string $break [optional]

Character used to break the string. | Default: "\n"

* * @psalm-mutation-free * * @return static */ public function hardWrap($width, $break = "\n"): self { return $this->lineWrap($width, $break, false); } /** * Returns true if the string contains a lower case char, false otherwise * * EXAMPLE: * s('fòôbàř')->hasLowerCase(); // true * * * @psalm-mutation-free * * @return bool *

Whether or not the string contains a lower case character.

*/ public function hasLowerCase(): bool { return $this->utf8::has_lowercase($this->str); } /** * Returns true if the string contains an upper case char, false otherwise. * * EXAMPLE: * s('fòôbàř')->hasUpperCase(); // false * * * @psalm-mutation-free * * @return bool *

Whether or not the string contains an upper case character.

*/ public function hasUpperCase(): bool { return $this->utf8::has_uppercase($this->str); } /** * Generate a hash value (message digest). * * EXAMPLE: * * * @see https://php.net/manual/en/function.hash.php * * @param string $algorithm *

Name of selected hashing algorithm (i.e. "md5", "sha256", "haval160,4", etc..)

* * @psalm-mutation-free * * @return static */ public function hash($algorithm): self { return static::create(\hash($algorithm, $this->str), $this->encoding); } /** * Decode the string from hex. * * EXAMPLE: * * * @psalm-mutation-free * * @return static */ public function hexDecode(): self { $string = \preg_replace_callback( '/\\\\x([0-9A-Fa-f]+)/', function (array $matched) { return (string) $this->utf8::hex_to_chr($matched[1]); }, $this->str ); return static::create( $string, $this->encoding ); } /** * Encode string to hex. * * EXAMPLE: * * * @psalm-mutation-free * * @return static */ public function hexEncode(): self { $string = \array_reduce( $this->chars(), function (string $str, string $char) { return $str . $this->utf8::chr_to_hex($char); }, '' ); return static::create( $string, $this->encoding ); } /** * Convert all HTML entities to their applicable characters. * * EXAMPLE: * s('&')->htmlDecode(); // '&' * * * @param int $flags [optional]

* A bitmask of one or more of the following flags, which specify how to handle quotes and * which document type to use. The default is ENT_COMPAT. * * Available flags constants * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Constant NameDescription
ENT_COMPATWill convert double-quotes and leave single-quotes alone.
ENT_QUOTESWill convert both double and single quotes.
ENT_NOQUOTESWill leave both double and single quotes unconverted.
ENT_HTML401 * Handle code as HTML 4.01. *
ENT_XML1 * Handle code as XML 1. *
ENT_XHTML * Handle code as XHTML. *
ENT_HTML5 * Handle code as HTML 5. *
*

* * @psalm-mutation-free * * @return static *

Object with the resulting $str after being html decoded.

*/ public function htmlDecode(int $flags = \ENT_COMPAT): self { return static::create( $this->utf8::html_entity_decode( $this->str, $flags, $this->encoding ), $this->encoding ); } /** * Convert all applicable characters to HTML entities. * * EXAMPLE: * s('&')->htmlEncode(); // '&' * * * @param int $flags [optional]

* A bitmask of one or more of the following flags, which specify how to handle quotes and * which document type to use. The default is ENT_COMPAT. * * Available flags constants * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Constant NameDescription
ENT_COMPATWill convert double-quotes and leave single-quotes alone.
ENT_QUOTESWill convert both double and single quotes.
ENT_NOQUOTESWill leave both double and single quotes unconverted.
ENT_HTML401 * Handle code as HTML 4.01. *
ENT_XML1 * Handle code as XML 1. *
ENT_XHTML * Handle code as XHTML. *
ENT_HTML5 * Handle code as HTML 5. *
*

* * @psalm-mutation-free * * @return static *

Object with the resulting $str after being html encoded.

*/ public function htmlEncode(int $flags = \ENT_COMPAT): self { return static::create( $this->utf8::htmlentities( $this->str, $flags, $this->encoding ), $this->encoding ); } /** * Capitalizes the first word of the string, replaces underscores with * spaces, and strips '_id'. * * EXAMPLE: * s('author_id')->humanize(); // 'Author' * * * @psalm-mutation-free * * @return static *

Object with a humanized $str.

*/ public function humanize(): self { return static::create( $this->utf8::str_humanize($this->str), $this->encoding ); } /** * Determine if the current string exists in another string. By * default, the comparison is case-sensitive, but can be made insensitive * by setting $caseSensitive to false. * * EXAMPLE: * * * @param string $str

The string to compare against.

* @param bool $caseSensitive [optional]

Whether or not to enforce case-sensitivity. Default: true

* * @psalm-mutation-free * * @return bool */ public function in(string $str, bool $caseSensitive = true): bool { if ($caseSensitive) { return \strpos($str, $this->str) !== false; } return \stripos($str, $this->str) !== false; } /** * Returns the index of the first occurrence of $needle in the string, * and false if not found. Accepts an optional offset from which to begin * the search. * * EXAMPLE: * s('string')->indexOf('ing'); // 3 * * * @param string $needle

Substring to look for.

* @param int $offset [optional]

Offset from which to search. Default: 0

* * @psalm-mutation-free * * @return false|int *

The occurrence's index if found, otherwise false.

*/ public function indexOf(string $needle, int $offset = 0) { return $this->utf8::strpos( $this->str, $needle, $offset, $this->encoding ); } /** * Returns the index of the first occurrence of $needle in the string, * and false if not found. Accepts an optional offset from which to begin * the search. * * EXAMPLE: * s('string')->indexOfIgnoreCase('ING'); // 3 * * * @param string $needle

Substring to look for.

* @param int $offset [optional]

Offset from which to search. Default: 0

* * @psalm-mutation-free * * @return false|int *

The occurrence's index if found, otherwise false.

*/ public function indexOfIgnoreCase(string $needle, int $offset = 0) { return $this->utf8::stripos( $this->str, $needle, $offset, $this->encoding ); } /** * Returns the index of the last occurrence of $needle in the string, * and false if not found. Accepts an optional offset from which to begin * the search. Offsets may be negative to count from the last character * in the string. * * EXAMPLE: * s('foobarfoo')->indexOfLast('foo'); // 10 * * * @param string $needle

Substring to look for.

* @param int $offset [optional]

Offset from which to search. Default: 0

* * @psalm-mutation-free * * @return false|int *

The last occurrence's index if found, otherwise false.

*/ public function indexOfLast(string $needle, int $offset = 0) { return $this->utf8::strrpos( $this->str, $needle, $offset, $this->encoding ); } /** * Returns the index of the last occurrence of $needle in the string, * and false if not found. Accepts an optional offset from which to begin * the search. Offsets may be negative to count from the last character * in the string. * * EXAMPLE: * s('fooBarFoo')->indexOfLastIgnoreCase('foo'); // 10 * * * @param string $needle

Substring to look for.

* @param int $offset [optional]

Offset from which to search. Default: 0

* * @psalm-mutation-free * * @return false|int *

The last occurrence's index if found, otherwise false.

*/ public function indexOfLastIgnoreCase(string $needle, int $offset = 0) { return $this->utf8::strripos( $this->str, $needle, $offset, $this->encoding ); } /** * Inserts $substring into the string at the $index provided. * * EXAMPLE: * s('fòôbř')->insert('à', 4); // 'fòôbàř' * * * @param string $substring

String to be inserted.

* @param int $index

The index at which to insert the substring.

* * @psalm-mutation-free * * @return static *

Object with the resulting $str after the insertion.

*/ public function insert(string $substring, int $index): self { return static::create( $this->utf8::str_insert( $this->str, $substring, $index, $this->encoding ), $this->encoding ); } /** * Returns true if the string contains the $pattern, otherwise false. * * WARNING: Asterisks ("*") are translated into (".*") zero-or-more regular * expression wildcards. * * EXAMPLE: * s('Foo\\Bar\\Lall')->is('*\\Bar\\*'); // true * * * @credit Originally from Laravel, thanks Taylor. * * @param string $pattern

The string or pattern to match against.

* * @psalm-mutation-free * * @return bool *

Whether or not we match the provided pattern.

*/ public function is(string $pattern): bool { if ($this->toString() === $pattern) { return true; } $quotedPattern = \preg_quote($pattern, '/'); $replaceWildCards = \str_replace('\*', '.*', $quotedPattern); return $this->matchesPattern('^' . $replaceWildCards . '\z'); } /** * Returns true if the string contains only alphabetic chars, false otherwise. * * EXAMPLE: * s('丹尼爾')->isAlpha(); // true * * * @psalm-mutation-free * * @return bool *

Whether or not $str contains only alphabetic chars.

*/ public function isAlpha(): bool { return $this->utf8::is_alpha($this->str); } /** * Returns true if the string contains only alphabetic and numeric chars, false otherwise. * * EXAMPLE: * s('دانيال1')->isAlphanumeric(); // true * * * @psalm-mutation-free * * @return bool *

Whether or not $str contains only alphanumeric chars.

*/ public function isAlphanumeric(): bool { return $this->utf8::is_alphanumeric($this->str); } /** * Checks if a string is 7 bit ASCII. * * EXAMPLE: s('白')->isAscii; // false * * @psalm-mutation-free * * @return bool *

* true if it is ASCII
* false otherwise *

* * @noinspection GetSetMethodCorrectnessInspection */ public function isAscii(): bool { return $this->utf8::is_ascii($this->str); } /** * Returns true if the string is base64 encoded, false otherwise. * * EXAMPLE: * s('Zm9vYmFy')->isBase64(); // true * * * @param bool $emptyStringIsValid * * @psalm-mutation-free * * @return bool *

Whether or not $str is base64 encoded.

*/ public function isBase64($emptyStringIsValid = true): bool { return $this->utf8::is_base64($this->str, $emptyStringIsValid); } /** * Check if the input is binary... (is look like a hack). * * EXAMPLE: s(01)->isBinary(); // true * * @psalm-mutation-free * * @return bool */ public function isBinary(): bool { return $this->utf8::is_binary($this->str); } /** * Returns true if the string contains only whitespace chars, false otherwise. * * EXAMPLE: * s("\n\t \v\f")->isBlank(); // true * * * @psalm-mutation-free * * @return bool *

Whether or not $str contains only whitespace characters.

*/ public function isBlank(): bool { return $this->utf8::is_blank($this->str); } /** * Checks if the given string is equal to any "Byte Order Mark". * * WARNING: Use "s::string_has_bom()" if you will check BOM in a string. * * EXAMPLE: s->("\xef\xbb\xbf")->isBom(); // true * * @psalm-mutation-free * * @return bool *

true if the $utf8_chr is Byte Order Mark, false otherwise.

*/ public function isBom(): bool { return $this->utf8::is_bom($this->str); } /** * Returns true if the string contains a valid E-Mail address, false otherwise. * * EXAMPLE: * s('lars@moelleken.org')->isEmail(); // true * * * @param bool $useExampleDomainCheck [optional]

Default: false

* @param bool $useTypoInDomainCheck [optional]

Default: false

* @param bool $useTemporaryDomainCheck [optional]

Default: false

* @param bool $useDnsCheck [optional]

Default: false

* * @psalm-mutation-free * * @return bool *

Whether or not $str contains a valid E-Mail address.

*/ public function isEmail( bool $useExampleDomainCheck = false, bool $useTypoInDomainCheck = false, bool $useTemporaryDomainCheck = false, bool $useDnsCheck = false ): bool { /** * @psalm-suppress ImpureMethodCall -> add more psalm stuff to the email-check class */ return EmailCheck::isValid($this->str, $useExampleDomainCheck, $useTypoInDomainCheck, $useTemporaryDomainCheck, $useDnsCheck); } /** * Determine whether the string is considered to be empty. * * A variable is considered empty if it does not exist or if its value equals FALSE. * * EXAMPLE: * s('')->isEmpty(); // true * * * @psalm-mutation-free * * @return bool *

Whether or not $str is empty().

*/ public function isEmpty(): bool { return $this->utf8::is_empty($this->str); } /** * Determine whether the string is equals to $str. * Alias for isEqualsCaseSensitive() * * EXAMPLE: * s('foo')->isEquals('foo'); // true * * * @param string|Stringy ...$str * * @psalm-mutation-free * * @return bool */ public function isEquals(...$str): bool { return $this->isEqualsCaseSensitive(...$str); } /** * Determine whether the string is equals to $str. * * EXAMPLE: * * * @param float|int|string|Stringy ...$str

The string to compare.

* * @psalm-mutation-free * * @return bool *

Whether or not $str is equals.

*/ public function isEqualsCaseInsensitive(...$str): bool { $strUpper = $this->toUpperCase()->str; foreach ($str as $strTmp) { /** * @psalm-suppress RedundantConditionGivenDocblockType - wait for union-types :) */ if ($strTmp instanceof self) { if ($strUpper !== $strTmp->toUpperCase()->str) { return false; } } elseif (\is_scalar($strTmp)) { if ($strUpper !== $this->utf8::strtoupper((string) $strTmp, $this->encoding)) { return false; } } else { throw new \InvalidArgumentException('expected: int|float|string|Stringy -> given: ' . \print_r($strTmp, true) . ' [' . \gettype($strTmp) . ']'); } } return true; } /** * Determine whether the string is equals to $str. * * EXAMPLE: * * * @param float|int|string|Stringy ...$str

The string to compare.

* * @psalm-mutation-free * * @return bool *

Whether or not $str is equals.

*/ public function isEqualsCaseSensitive(...$str): bool { foreach ($str as $strTmp) { /** * @psalm-suppress RedundantConditionGivenDocblockType - wait for union-types :) */ if ($strTmp instanceof self) { if ($this->str !== $strTmp->str) { return false; } } elseif (\is_scalar($strTmp)) { if ($this->str !== (string) $strTmp) { return false; } } else { throw new \InvalidArgumentException('expected: int|float|string|Stringy -> given: ' . \print_r($strTmp, true) . ' [' . \gettype($strTmp) . ']'); } } return true; } /** * Returns true if the string contains only hexadecimal chars, false otherwise. * * EXAMPLE: * s('A102F')->isHexadecimal(); // true * * * @psalm-mutation-free * * @return bool *

Whether or not $str contains only hexadecimal chars.

*/ public function isHexadecimal(): bool { return $this->utf8::is_hexadecimal($this->str); } /** * Returns true if the string contains HTML-Tags, false otherwise. * * EXAMPLE: * s('

foo

')->isHtml(); // true *
* * @psalm-mutation-free * * @return bool *

Whether or not $str contains HTML-Tags.

*/ public function isHtml(): bool { return $this->utf8::is_html($this->str); } /** * Returns true if the string is JSON, false otherwise. Unlike json_decode * in PHP 5.x, this method is consistent with PHP 7 and other JSON parsers, * in that an empty string is not considered valid JSON. * * EXAMPLE: * s('{"foo":"bar"}')->isJson(); // true * * * @param bool $onlyArrayOrObjectResultsAreValid * * @psalm-mutation-free * * @return bool *

Whether or not $str is JSON.

*/ public function isJson($onlyArrayOrObjectResultsAreValid = false): bool { /** * @psalm-suppress ImpureMethodCall -> add more psalm stuff to vendor stuff? */ return $this->utf8::is_json( $this->str, $onlyArrayOrObjectResultsAreValid ); } /** * Returns true if the string contains only lower case chars, false otherwise. * * EXAMPLE: * s('fòôbàř')->isLowerCase(); // true * * * @psalm-mutation-free * * @return bool *

Whether or not $str contains only lower case characters.

*/ public function isLowerCase(): bool { return $this->utf8::is_lowercase($this->str); } /** * Determine whether the string is considered to be NOT empty. * * A variable is considered NOT empty if it does exist or if its value equals TRUE. * * EXAMPLE: * s('')->isNotEmpty(); // false * * * @psalm-mutation-free * * @return bool *

Whether or not $str is empty().

*/ public function isNotEmpty(): bool { return !$this->utf8::is_empty($this->str); } /** * Determine if the string is composed of numeric characters. * * EXAMPLE: * * * @psalm-mutation-free * * @return bool */ public function isNumeric(): bool { return \is_numeric($this->str); } /** * Determine if the string is composed of printable (non-invisible) characters. * * EXAMPLE: * * * @psalm-mutation-free * * @return bool */ public function isPrintable(): bool { return $this->utf8::is_printable($this->str); } /** * Determine if the string is composed of punctuation characters. * * EXAMPLE: * * * @psalm-mutation-free * * @return bool */ public function isPunctuation(): bool { return $this->utf8::is_punctuation($this->str); } /** * Returns true if the string is serialized, false otherwise. * * EXAMPLE: * s('a:1:{s:3:"foo";s:3:"bar";}')->isSerialized(); // true * * * @psalm-mutation-free * * @return bool *

Whether or not $str is serialized.

*/ public function isSerialized(): bool { return $this->utf8::is_serialized($this->str); } /** * Check if two strings are similar. * * EXAMPLE: * * * @param string $str

The string to compare against.

* @param float $minPercentForSimilarity [optional]

The percentage of needed similarity. | Default: 80%

* * @psalm-mutation-free * * @return bool */ public function isSimilar(string $str, float $minPercentForSimilarity = 80.0): bool { return $this->similarity($str) >= $minPercentForSimilarity; } /** * Returns true if the string contains only lower case chars, false * otherwise. * * EXAMPLE: * s('FÒÔBÀŘ')->isUpperCase(); // true * * * @psalm-mutation-free * * @return bool *

Whether or not $str contains only lower case characters.

*/ public function isUpperCase(): bool { return $this->utf8::is_uppercase($this->str); } /** * /** * Check if $url is an correct url. * * @param bool $disallow_localhost * * @psalm-mutation-free * * @return bool */ public function isUrl(bool $disallow_localhost = false): bool { return $this->utf8::is_url($this->str, $disallow_localhost); } /** * Check if the string is UTF-16. * * @psalm-mutation-free * * @return false|int * false if is't not UTF-16,
* 1 for UTF-16LE,
* 2 for UTF-16BE */ public function isUtf16() { return $this->utf8::is_utf16($this->str); } /** * Check if the string is UTF-32. * * @psalm-mutation-free * * @return false|int * false if is't not UTF-32,
* 1 for UTF-32LE,
* 2 for UTF-32BE */ public function isUtf32() { return $this->utf8::is_utf32($this->str); } /** * Checks whether the passed input contains only byte sequences that appear valid UTF-8. * * EXAMPLE: * s('Iñtërnâtiônàlizætiøn')->isUtf8(); // true * // * s("Iñtërnâtiônàlizætiøn\xA0\xA1")->isUtf8(); // false * * * @param bool $strict

Check also if the string is not UTF-16 or UTF-32.

* * @psalm-mutation-free * * @return bool */ public function isUtf8(bool $strict = false): bool { return $this->utf8::is_utf8($this->str, $strict); } /** * Returns true if the string contains only whitespace chars, false otherwise. * * EXAMPLE: * * * @psalm-mutation-free * * @return bool *

Whether or not $str contains only whitespace characters.

*/ public function isWhitespace(): bool { return $this->isBlank(); } /** * Returns value which can be serialized by json_encode(). * * EXAMPLE: * * * @noinspection ReturnTypeCanBeDeclaredInspection * * @psalm-mutation-free * * @return string The current value of the $str property */ #[\ReturnTypeWillChange] public function jsonSerialize() { return (string) $this; } /** * Convert the string to kebab-case. * * EXAMPLE: * * * @psalm-mutation-free * * @return static */ public function kebabCase(): self { $words = \array_map( static function (self $word) { return $word->toLowerCase(); }, $this->words('', true) ); return new static(\implode('-', $words), $this->encoding); } /** * Returns the last $n characters of the string. * * EXAMPLE: * s('fòôbàř')->last(3); // 'bàř' * * * @param int $n

Number of characters to retrieve from the end.

* * @psalm-mutation-free * * @return static *

Object with its $str being the last $n chars.

*/ public function last(int $n): self { return static::create( $this->utf8::str_last_char( $this->str, $n, $this->encoding ), $this->encoding ); } /** * Gets the substring after (or before via "$beforeNeedle") the last occurrence of the "$needle". * If no match is found returns new empty Stringy object. * * EXAMPLE: * * * @param string $needle

The string to look for.

* @param bool $beforeNeedle [optional]

Default: false

* * @psalm-mutation-free * * @return static */ public function lastSubstringOf(string $needle, bool $beforeNeedle = false): self { return static::create( $this->utf8::str_substr_last( $this->str, $needle, $beforeNeedle, $this->encoding ), $this->encoding ); } /** * Gets the substring after (or before via "$beforeNeedle") the last occurrence of the "$needle". * If no match is found returns new empty Stringy object. * * EXAMPLE: * * * @param string $needle

The string to look for.

* @param bool $beforeNeedle [optional]

Default: false

* * @psalm-mutation-free * * @return static */ public function lastSubstringOfIgnoreCase(string $needle, bool $beforeNeedle = false): self { return static::create( $this->utf8::str_isubstr_last( $this->str, $needle, $beforeNeedle, $this->encoding ), $this->encoding ); } /** * Returns the length of the string. * * EXAMPLE: * s('fòôbàř')->length(); // 6 * * * @psalm-mutation-free * * @return int *

The number of characters in $str given the encoding.

*/ public function length(): int { return (int) $this->utf8::strlen($this->str, $this->encoding); } /** * Line-Wrap the string after $limit, but also after the next word. * * EXAMPLE: * * * @param int $limit [optional]

The column width.

* @param string $break [optional]

The line is broken using the optional break parameter.

* @param bool $add_final_break [optional]

* If this flag is true, then the method will add a $break at the end * of the result string. *

* @param string|null $delimiter [optional]

* You can change the default behavior, where we split the string by newline. *

* * @psalm-mutation-free * * @return static */ public function lineWrap( int $limit, string $break = "\n", bool $add_final_break = true, string $delimiter = null ): self { return static::create( $this->utf8::wordwrap_per_line( $this->str, $limit, $break, true, $add_final_break, $delimiter ), $this->encoding ); } /** * Line-Wrap the string after $limit, but also after the next word. * * EXAMPLE: * * * @param int $limit [optional]

The column width.

* @param string $break [optional]

The line is broken using the optional break parameter.

* @param bool $add_final_break [optional]

* If this flag is true, then the method will add a $break at the end * of the result string. *

* @param string|null $delimiter [optional]

* You can change the default behavior, where we split the string by newline. *

* * @psalm-mutation-free * * @return static */ public function lineWrapAfterWord( int $limit, string $break = "\n", bool $add_final_break = true, string $delimiter = null ): self { return static::create( $this->utf8::wordwrap_per_line( $this->str, $limit, $break, false, $add_final_break, $delimiter ), $this->encoding ); } /** * Splits on newlines and carriage returns, returning an array of Stringy * objects corresponding to the lines in the string. * * EXAMPLE: * s("fòô\r\nbàř\n")->lines(); // ['fòô', 'bàř', ''] * * * @psalm-mutation-free * * @return static[] *

An array of Stringy objects.

* * @phpstan-return array */ public function lines(): array { if ($this->str === '') { return [static::create('')]; } $strings = $this->utf8::str_to_lines($this->str); /** @noinspection AlterInForeachInspection */ foreach ($strings as &$str) { $str = static::create($str, $this->encoding); } /** @noinspection PhpSillyAssignmentInspection */ /** @var static[] $strings */ $strings = $strings; return $strings; } /** * Splits on newlines and carriage returns, returning an array of Stringy * objects corresponding to the lines in the string. * * EXAMPLE: * * * @psalm-mutation-free * * @return CollectionStringy|static[] *

An collection of Stringy objects.

* * @phpstan-return CollectionStringy */ public function linesCollection(): CollectionStringy { /** * @psalm-suppress ImpureMethodCall -> add more psalm stuff to the collection class */ return CollectionStringy::create( $this->lines() ); } /** * Returns the longest common prefix between the string and $otherStr. * * EXAMPLE: * s('foobar')->longestCommonPrefix('foobaz'); // 'fooba' * * * @param string $otherStr

Second string for comparison.

* * @psalm-mutation-free * * @return static *

Object with its $str being the longest common prefix.

*/ public function longestCommonPrefix(string $otherStr): self { return static::create( $this->utf8::str_longest_common_prefix( $this->str, $otherStr, $this->encoding ), $this->encoding ); } /** * Returns the longest common substring between the string and $otherStr. * In the case of ties, it returns that which occurs first. * * EXAMPLE: * s('foobar')->longestCommonSubstring('boofar'); // 'oo' * * * @param string $otherStr

Second string for comparison.

* * @psalm-mutation-free * * @return static *

Object with its $str being the longest common substring.

*/ public function longestCommonSubstring(string $otherStr): self { return static::create( $this->utf8::str_longest_common_substring( $this->str, $otherStr, $this->encoding ), $this->encoding ); } /** * Returns the longest common suffix between the string and $otherStr. * * EXAMPLE: * s('fòôbàř')->longestCommonSuffix('fòrbàř'); // 'bàř' * * * @param string $otherStr

Second string for comparison.

* * @psalm-mutation-free * * @return static *

Object with its $str being the longest common suffix.

*/ public function longestCommonSuffix(string $otherStr): self { return static::create( $this->utf8::str_longest_common_suffix( $this->str, $otherStr, $this->encoding ), $this->encoding ); } /** * Converts the first character of the string to lower case. * * EXAMPLE: * s('Σ Foo')->lowerCaseFirst(); // 'σ Foo' * * * @psalm-mutation-free * * @return static *

Object with the first character of $str being lower case.

*/ public function lowerCaseFirst(): self { return static::create( $this->utf8::lcfirst($this->str, $this->encoding), $this->encoding ); } /** * Determine if the string matches another string regardless of case. * Alias for isEqualsCaseInsensitive() * * EXAMPLE: * * * @psalm-mutation-free * * @param string|Stringy ...$str *

The string to compare against.

* * @psalm-mutation-free * * @return bool */ public function matchCaseInsensitive(...$str): bool { return $this->isEqualsCaseInsensitive(...$str); } /** * Determine if the string matches another string. * Alias for isEqualsCaseSensitive() * * EXAMPLE: * * * @psalm-mutation-free * * @param string|Stringy ...$str *

The string to compare against.

* * @psalm-mutation-free * * @return bool */ public function matchCaseSensitive(...$str): bool { return $this->isEqualsCaseSensitive(...$str); } /** * Create a md5 hash from the current string. * * @psalm-mutation-free * * @return static */ public function md5(): self { return static::create($this->hash('md5'), $this->encoding); } /** * Replace all breaks [
| \r\n | \r | \n | ...] into "
". * * EXAMPLE: * * * @return static */ public function newLineToHtmlBreak(): self { return $this->removeHtmlBreak('
'); } /** * Get every nth character of the string. * * EXAMPLE: * * * @param int $step

The number of characters to step.

* @param int $offset [optional]

The string offset to start at.

* * @psalm-mutation-free * * @return static */ public function nth(int $step, int $offset = 0): self { $length = $step - 1; $substring = $this->substr($offset)->toString(); if ($substring === '') { return new static('', $this->encoding); } \preg_match_all( "/(?:^|(?:.|\p{L}|\w){" . $length . "})(.|\p{L}|\w)/u", $substring, $matches ); return new static(\implode('', $matches[1] ?? []), $this->encoding); } /** * Returns the integer value of the current string. * * EXAMPLE: * s('foo1 ba2r')->extractIntegers(); // '12' * * * @psalm-mutation-free * * @return static */ public function extractIntegers(): self { if ($this->str === '') { return new static('', $this->encoding); } \preg_match_all('/(?\d+)/', $this->str, $matches); return static::create( \implode('', $matches['integers'] ?? []), $this->encoding ); } /** * Returns the special chars of the current string. * * EXAMPLE: * s('foo1 ba2!r')->extractSpecialCharacters(); // '!' * * * @psalm-mutation-free * * @return static */ public function extractSpecialCharacters(): self { if ($this->str === '') { return new static('', $this->encoding); } // no letter, no digit, no space \preg_match_all('/((?![\p{L}0-9\s]+).)/u', $this->str, $matches); return static::create( \implode('', $matches[0] ?? []), $this->encoding ); } /** * Returns whether or not a character exists at an index. Offsets may be * negative to count from the last character in the string. Implements * part of the ArrayAccess interface. * * EXAMPLE: * * * @param int $offset

The index to check.

* * @psalm-mutation-free * * @return bool *

Whether or not the index exists.

*/ public function offsetExists($offset): bool { return $this->utf8::str_offset_exists( $this->str, $offset, $this->encoding ); } /** * Returns the character at the given index. Offsets may be negative to * count from the last character in the string. Implements part of the * ArrayAccess interface, and throws an OutOfBoundsException if the index * does not exist. * * EXAMPLE: * * * @param int $offset

The index from which to retrieve the char.

* * @throws \OutOfBoundsException *

If the positive or negative offset does not exist.

* * @return string *

The character at the specified index.

* * @psalm-mutation-free */ public function offsetGet($offset): string { return $this->utf8::str_offset_get($this->str, $offset, $this->encoding); } /** * Implements part of the ArrayAccess interface, but throws an exception * when called. This maintains the immutability of Stringy objects. * * EXAMPLE: * * * @param int $offset

The index of the character.

* @param mixed $value

Value to set.

* * @throws \Exception *

When called.

* * @return void */ #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { // Stringy is immutable, cannot directly set char throw new \Exception('Stringy object is immutable, cannot modify char'); } /** * Implements part of the ArrayAccess interface, but throws an exception * when called. This maintains the immutability of Stringy objects. * * EXAMPLE: * * * @param int $offset

The index of the character.

* * @throws \Exception *

When called.

* * @return void */ #[\ReturnTypeWillChange] public function offsetUnset($offset) { // Don't allow directly modifying the string throw new \Exception('Stringy object is immutable, cannot unset char'); } /** * Pads the string to a given length with $padStr. If length is less than * or equal to the length of the string, no padding takes places. The * default string used for padding is a space, and the default type (one of * 'left', 'right', 'both') is 'right'. Throws an InvalidArgumentException * if $padType isn't one of those 3 values. * * EXAMPLE: * s('fòôbàř')->pad(9, '-/', 'left'); // '-/-fòôbàř' * * * @param int $length

Desired string length after padding.

* @param string $padStr [optional]

String used to pad, defaults to space. Default: ' '

* @param string $padType [optional]

One of 'left', 'right', 'both'. Default: 'right'

* * @throws \InvalidArgumentException *

If $padType isn't one of 'right', 'left' or 'both'.

* * @return static *

Object with a padded $str.

* * @psalm-mutation-free */ public function pad(int $length, string $padStr = ' ', string $padType = 'right'): self { return static::create( $this->utf8::str_pad( $this->str, $length, $padStr, $padType, $this->encoding ) ); } /** * Returns a new string of a given length such that both sides of the * string are padded. Alias for pad() with a $padType of 'both'. * * EXAMPLE: * s('foo bar')->padBoth(9, ' '); // ' foo bar ' * * * @param int $length

Desired string length after padding.

* @param string $padStr [optional]

String used to pad, defaults to space. Default: ' '

* * @psalm-mutation-free * * @return static *

String with padding applied.

*/ public function padBoth(int $length, string $padStr = ' '): self { return static::create( $this->utf8::str_pad_both( $this->str, $length, $padStr, $this->encoding ) ); } /** * Returns a new string of a given length such that the beginning of the * string is padded. Alias for pad() with a $padType of 'left'. * * EXAMPLE: * s('foo bar')->padLeft(9, ' '); // ' foo bar' * * * @param int $length

Desired string length after padding.

* @param string $padStr [optional]

String used to pad, defaults to space. Default: ' '

* * @psalm-mutation-free * * @return static *

String with left padding.

*/ public function padLeft(int $length, string $padStr = ' '): self { return static::create( $this->utf8::str_pad_left( $this->str, $length, $padStr, $this->encoding ) ); } /** * Returns a new string of a given length such that the end of the string * is padded. Alias for pad() with a $padType of 'right'. * * EXAMPLE: * s('foo bar')->padRight(10, '_*'); // 'foo bar_*_' * * * @param int $length

Desired string length after padding.

* @param string $padStr [optional]

String used to pad, defaults to space. Default: ' '

* * @psalm-mutation-free * * @return static *

String with right padding.

*/ public function padRight(int $length, string $padStr = ' '): self { return static::create( $this->utf8::str_pad_right( $this->str, $length, $padStr, $this->encoding ) ); } /** * Convert the string to PascalCase. * Alias for studlyCase() * * EXAMPLE: * * * @psalm-mutation-free * * @return static */ public function pascalCase(): self { return $this->studlyCase(); } /** * Returns a new string starting with $prefix. * * EXAMPLE: * s('bàř')->prepend('fòô'); // 'fòôbàř' * * * @param string ...$prefix

The string to append.

* * @psalm-mutation-free * * @return static *

Object with appended $prefix.

*/ public function prepend(string ...$prefix): self { if (\count($prefix) <= 1) { $prefix = $prefix[0]; } else { $prefix = \implode('', $prefix); } return static::create($prefix . $this->str, $this->encoding); } /** * Returns a new string starting with $prefix. * * EXAMPLE: * * * @param CollectionStringy|static ...$prefix

The Stringy objects to append.

* * @phpstan-param CollectionStringy|static ...$prefix * * @psalm-mutation-free * * @return static *

Object with appended $prefix.

*/ public function prependStringy(...$prefix): self { $prefixStr = ''; foreach ($prefix as $prefixTmp) { if ($prefixTmp instanceof CollectionStringy) { $prefixStr .= $prefixTmp->implode(''); } else { $prefixStr .= $prefixTmp->toString(); } } return static::create($prefixStr . $this->str, $this->encoding); } /** * Replaces all occurrences of $pattern in $str by $replacement. * * EXAMPLE: * s('fòô ')->regexReplace('f[òô]+\s', 'bàř'); // 'bàř' * s('fò')->regexReplace('(ò)', '\\1ô'); // 'fòô' * * * @param string $pattern

The regular expression pattern.

* @param string $replacement

The string to replace with.

* @param string $options [optional]

Matching conditions to be used.

* @param string $delimiter [optional]

Delimiter the the regex. Default: '/'

* * @psalm-mutation-free * * @return static *

Object with the result2ing $str after the replacements.

*/ public function regexReplace( string $pattern, string $replacement, string $options = '', string $delimiter = '/' ): self { return static::create( $this->utf8::regex_replace( $this->str, $pattern, $replacement, $options, $delimiter ), $this->encoding ); } /** * Remove html via "strip_tags()" from the string. * * EXAMPLE: * s('řàb <ô>òf\', ô
foo lall')->removeHtml('

'); // 'řàb òf\', ô
foo lall' *
* * @param string $allowableTags [optional]

You can use the optional second parameter to specify tags which should * not be stripped. Default: null *

* * @psalm-mutation-free * * @return static */ public function removeHtml(string $allowableTags = ''): self { return static::create( $this->utf8::remove_html($this->str, $allowableTags), $this->encoding ); } /** * Remove all breaks [
| \r\n | \r | \n | ...] from the string. * * EXAMPLE: * s('řàb <ô>òf\', ô
foo lall')->removeHtmlBreak(''); // 'řàb <ô>òf\', ô< foo lall' *
* * @param string $replacement [optional]

Default is a empty string.

* * @psalm-mutation-free * * @return static */ public function removeHtmlBreak(string $replacement = ''): self { return static::create( $this->utf8::remove_html_breaks($this->str, $replacement), $this->encoding ); } /** * Returns a new string with the prefix $substring removed, if present. * * EXAMPLE: * s('fòôbàř')->removeLeft('fòô'); // 'bàř' * * * @param string $substring

The prefix to remove.

* * @psalm-mutation-free * * @return static *

Object having a $str without the prefix $substring.

*/ public function removeLeft(string $substring): self { return static::create( $this->utf8::remove_left($this->str, $substring, $this->encoding), $this->encoding ); } /** * Returns a new string with the suffix $substring removed, if present. * * EXAMPLE: * s('fòôbàř')->removeRight('bàř'); // 'fòô' * * * @param string $substring

The suffix to remove.

* * @psalm-mutation-free * * @return static *

Object having a $str without the suffix $substring.

*/ public function removeRight(string $substring): self { return static::create( $this->utf8::remove_right($this->str, $substring, $this->encoding), $this->encoding ); } /** * Try to remove all XSS-attacks from the string. * * EXAMPLE: * s('')->removeXss(); // '' * * * @psalm-mutation-free * * @return static */ public function removeXss(): self { /** * @var AntiXSS|null * * @psalm-suppress ImpureStaticVariable */ static $antiXss = null; if ($antiXss === null) { $antiXss = new AntiXSS(); } /** * @psalm-suppress ImpureMethodCall -> add more psalm stuff to the anti-xss class */ $str = $antiXss->xss_clean($this->str); return static::create($str, $this->encoding); } /** * Returns a repeated string given a multiplier. * * EXAMPLE: * s('α')->repeat(3); // 'ααα' * * * @param int $multiplier

The number of times to repeat the string.

* * @psalm-mutation-free * * @return static *

Object with a repeated str.

*/ public function repeat(int $multiplier): self { return static::create( \str_repeat($this->str, $multiplier), $this->encoding ); } /** * Replaces all occurrences of $search in $str by $replacement. * * EXAMPLE: * s('fòô bàř fòô bàř')->replace('fòô ', ''); // 'bàř bàř' * * * @param string $search

The needle to search for.

* @param string $replacement

The string to replace with.

* @param bool $caseSensitive [optional]

Whether or not to enforce case-sensitivity. Default: true

* * @psalm-mutation-free * * @return static *

Object with the resulting $str after the replacements.

*/ public function replace(string $search, string $replacement, bool $caseSensitive = true): self { if ($search === '' && $replacement === '') { return static::create($this->str, $this->encoding); } if ($this->str === '' && $search === '') { return static::create($replacement, $this->encoding); } if ($caseSensitive) { return static::create( \str_replace($search, $replacement, $this->str), $this->encoding ); } return static::create( $this->utf8::str_ireplace($search, $replacement, $this->str), $this->encoding ); } /** * Replaces all occurrences of $search in $str by $replacement. * * EXAMPLE: * s('fòô bàř lall bàř')->replaceAll(['fòÔ ', 'lall'], '', false); // 'bàř bàř' * * * @param string[] $search

The elements to search for.

* @param string|string[] $replacement

The string to replace with.

* @param bool $caseSensitive [optional]

Whether or not to enforce case-sensitivity. Default: true

* * @psalm-mutation-free * * @return static *

Object with the resulting $str after the replacements.

*/ public function replaceAll(array $search, $replacement, bool $caseSensitive = true): self { if ($caseSensitive) { return static::create( \str_replace($search, $replacement, $this->str), $this->encoding ); } return static::create( $this->utf8::str_ireplace($search, $replacement, $this->str), $this->encoding ); } /** * Replaces all occurrences of $search from the beginning of string with $replacement. * * EXAMPLE: * s('fòô bàř fòô bàř')->replaceBeginning('fòô', ''); // ' bàř bàř' * * * @param string $search

The string to search for.

* @param string $replacement

The replacement.

* * @psalm-mutation-free * * @return static *

Object with the resulting $str after the replacements.

*/ public function replaceBeginning(string $search, string $replacement): self { return static::create( $this->utf8::str_replace_beginning($this->str, $search, $replacement), $this->encoding ); } /** * Replaces all occurrences of $search from the ending of string with $replacement. * * EXAMPLE: * s('fòô bàř fòô bàř')->replaceEnding('bàř', ''); // 'fòô bàř fòô ' * * * @param string $search

The string to search for.

* @param string $replacement

The replacement.

* * @psalm-mutation-free * * @return static *

Object with the resulting $str after the replacements.

*/ public function replaceEnding(string $search, string $replacement): self { return static::create( $this->utf8::str_replace_ending($this->str, $search, $replacement), $this->encoding ); } /** * Replaces first occurrences of $search from the beginning of string with $replacement. * * EXAMPLE: * * * @param string $search

The string to search for.

* @param string $replacement

The replacement.

* * @psalm-mutation-free * * @return static *

Object with the resulting $str after the replacements.

*/ public function replaceFirst(string $search, string $replacement): self { return static::create( $this->utf8::str_replace_first($search, $replacement, $this->str), $this->encoding ); } /** * Replaces last occurrences of $search from the ending of string with $replacement. * * EXAMPLE: * * * @param string $search

The string to search for.

* @param string $replacement

The replacement.

* * @psalm-mutation-free * * @return static *

Object with the resulting $str after the replacements.

*/ public function replaceLast(string $search, string $replacement): self { return static::create( $this->utf8::str_replace_last($search, $replacement, $this->str), $this->encoding ); } /** * Returns a reversed string. A multibyte version of strrev(). * * EXAMPLE: * s('fòôbàř')->reverse(); // 'řàbôòf' * * * @psalm-mutation-free * * @return static *

Object with a reversed $str.

*/ public function reverse(): self { return static::create($this->utf8::strrev($this->str), $this->encoding); } /** * Truncates the string to a given length, while ensuring that it does not * split words. If $substring is provided, and truncating occurs, the * string is further truncated so that the substring may be appended without * exceeding the desired length. * * EXAMPLE: * s('What are your plans today?')->safeTruncate(22, '...'); // 'What are your plans...' * * * @param int $length

Desired length of the truncated string.

* @param string $substring [optional]

The substring to append if it can fit. Default: ''

* @param bool $ignoreDoNotSplitWordsForOneWord * * @psalm-mutation-free * * @return static *

Object with the resulting $str after truncating.

*/ public function safeTruncate( int $length, string $substring = '', bool $ignoreDoNotSplitWordsForOneWord = true ): self { return static::create( $this->utf8::str_truncate_safe( $this->str, $length, $substring, $this->encoding, $ignoreDoNotSplitWordsForOneWord ), $this->encoding ); } /** * Set the internal character encoding. * * EXAMPLE: * * * @param string $new_encoding

The desired character encoding.

* * @psalm-mutation-free * * @return static */ public function setInternalEncoding(string $new_encoding): self { return new static($this->str, $new_encoding); } /** * Create a sha1 hash from the current string. * * EXAMPLE: * * * @psalm-mutation-free * * @return static */ public function sha1(): self { return static::create($this->hash('sha1'), $this->encoding); } /** * Create a sha256 hash from the current string. * * EXAMPLE: * * * @psalm-mutation-free * * @return static */ public function sha256(): self { return static::create($this->hash('sha256'), $this->encoding); } /** * Create a sha512 hash from the current string. * * EXAMPLE: * * * @psalm-mutation-free * * @return static */ public function sha512(): self { return static::create($this->hash('sha512'), $this->encoding); } /** * Shorten the string after $length, but also after the next word. * * EXAMPLE: * s('this is a test')->shortenAfterWord(2, '...'); // 'this...' * * * @param int $length

The given length.

* @param string $strAddOn [optional]

Default: '…'

* * @psalm-mutation-free * * @return static */ public function shortenAfterWord(int $length, string $strAddOn = '…'): self { return static::create( $this->utf8::str_limit_after_word($this->str, $length, $strAddOn), $this->encoding ); } /** * A multibyte string shuffle function. It returns a string with its * characters in random order. * * EXAMPLE: * s('fòôbàř')->shuffle(); // 'àôřbòf' * * * @return static *

Object with a shuffled $str.

*/ public function shuffle(): self { return static::create($this->utf8::str_shuffle($this->str), $this->encoding); } /** * Calculate the similarity between two strings. * * EXAMPLE: * * * @param string $str

The delimiting string.

* * @psalm-mutation-free * * @return float */ public function similarity(string $str): float { \similar_text($this->str, $str, $percent); return $percent; } /** * Returns the substring beginning at $start, and up to, but not including * the index specified by $end. If $end is omitted, the function extracts * the remaining string. If $end is negative, it is computed from the end * of the string. * * EXAMPLE: * s('fòôbàř')->slice(3, -1); // 'bà' * * * @param int $start

Initial index from which to begin extraction.

* @param int $end [optional]

Index at which to end extraction. Default: null

* * @psalm-mutation-free * * @return static *

Object with its $str being the extracted substring.

*/ public function slice(int $start, int $end = null): self { return static::create( $this->utf8::str_slice($this->str, $start, $end, $this->encoding), $this->encoding ); } /** * Converts the string into an URL slug. This includes replacing non-ASCII * characters with their closest ASCII equivalents, removing remaining * non-ASCII and non-alphanumeric characters, and replacing whitespace with * $separator. The separator defaults to a single dash, and the string * is also converted to lowercase. The language of the source string can * also be supplied for language-specific transliteration. * * EXAMPLE: * s('Using strings like fòô bàř')->slugify(); // 'using-strings-like-foo-bar' * * * @param string $separator [optional]

The string used to replace whitespace.

* @param string $language [optional]

Language of the source string.

* @param array $replacements [optional]

A map of replaceable strings.

* @param bool $replace_extra_symbols [optional]

Add some more replacements e.g. "£" with " * pound ".

* @param bool $use_str_to_lower [optional]

Use "string to lower" for the input.

* @param bool $use_transliterate [optional]

Use ASCII::to_transliterate() for unknown * chars.

* * @psalm-mutation-free * * @return static *

Object whose $str has been converted to an URL slug.

* * @phpstan-param ASCII::*_LANGUAGE_CODE $language * * @noinspection PhpTooManyParametersInspection */ public function slugify( string $separator = '-', string $language = 'en', array $replacements = [], bool $replace_extra_symbols = true, bool $use_str_to_lower = true, bool $use_transliterate = false ): self { return static::create( $this->ascii::to_slugify( $this->str, $separator, $language, $replacements, $replace_extra_symbols, $use_str_to_lower, $use_transliterate ), $this->encoding ); } /** * Convert the string to snake_case. * * EXAMPLE: * * * @psalm-mutation-free * * @return static */ public function snakeCase(): self { $words = \array_map( static function (self $word) { return $word->toLowerCase(); }, $this->words('', true) ); return new static(\implode('_', $words), $this->encoding); } /** * Convert a string to snake_case. * * EXAMPLE: * s('foo1 Bar')->snakeize(); // 'foo_1_bar' * * * @psalm-mutation-free * * @return static *

Object with $str in snake_case.

*/ public function snakeize(): self { return static::create( $this->utf8::str_snakeize($this->str, $this->encoding), $this->encoding ); } /** * Wrap the string after the first whitespace character after a given number * of characters. * * EXAMPLE: * * * @param int $width

Number of characters at which to wrap.

* @param string $break [optional]

Character used to break the string. | Default "\n"

* * @psalm-mutation-free * * @return static */ public function softWrap(int $width, string $break = "\n"): self { return $this->lineWrapAfterWord($width, $break, false); } /** * Splits the string with the provided regular expression, returning an * array of Stringy objects. An optional integer $limit will truncate the * results. * * EXAMPLE: * s('foo,bar,baz')->split(',', 2); // ['foo', 'bar'] * * * @param string $pattern

The regex with which to split the string.

* @param int $limit [optional]

Maximum number of results to return. Default: -1 === no * limit

* * @psalm-mutation-free * * @return static[] *

An array of Stringy objects.

* * @phpstan-return array */ public function split(string $pattern, int $limit = null): array { if ($this->str === '') { return []; } if ($limit === null) { $limit = -1; } $array = $this->utf8::str_split_pattern($this->str, $pattern, $limit); foreach ($array as &$value) { $value = static::create($value, $this->encoding); } /** @noinspection PhpSillyAssignmentInspection */ /** @var static[] $array */ $array = $array; return $array; } /** * Splits the string with the provided regular expression, returning an * collection of Stringy objects. An optional integer $limit will truncate the * results. * * EXAMPLE: * * * @param string $pattern

The regex with which to split the string.

* @param int $limit [optional]

Maximum number of results to return. Default: -1 === no * limit

* * @psalm-mutation-free * * @return CollectionStringy|static[] *

An collection of Stringy objects.

* * @phpstan-return CollectionStringy */ public function splitCollection(string $pattern, int $limit = null): CollectionStringy { /** * @psalm-suppress ImpureMethodCall -> add more psalm stuff to the collection class */ return CollectionStringy::create( $this->split($pattern, $limit) ); } /** * Returns true if the string begins with $substring, false otherwise. By * default, the comparison is case-sensitive, but can be made insensitive * by setting $caseSensitive to false. * * EXAMPLE: * s('FÒÔbàřbaz')->startsWith('fòôbàř', false); // true * * * @param string $substring

The substring to look for.

* @param bool $caseSensitive [optional]

Whether or not to enforce case-sensitivity. Default: true

* * @psalm-mutation-free * * @return bool *

Whether or not $str starts with $substring.

*/ public function startsWith(string $substring, bool $caseSensitive = true): bool { if ($caseSensitive) { return $this->utf8::str_starts_with($this->str, $substring); } return $this->utf8::str_istarts_with($this->str, $substring); } /** * Returns true if the string begins with any of $substrings, false otherwise. * By default the comparison is case-sensitive, but can be made insensitive by * setting $caseSensitive to false. * * EXAMPLE: * s('FÒÔbàřbaz')->startsWithAny(['fòô', 'bàř'], false); // true * * * @param string[] $substrings

Substrings to look for.

* @param bool $caseSensitive [optional]

Whether or not to enforce case-sensitivity. Default: true

* * @psalm-mutation-free * * @return bool *

Whether or not $str starts with $substring.

*/ public function startsWithAny(array $substrings, bool $caseSensitive = true): bool { if ($caseSensitive) { return $this->utf8::str_starts_with_any($this->str, $substrings); } return $this->utf8::str_istarts_with_any($this->str, $substrings); } /** * Remove one or more strings from the string. * * EXAMPLE: * * * @param string|string[] $search One or more strings to be removed * * @psalm-mutation-free * * @return static */ public function strip($search): self { if (\is_array($search)) { return $this->replaceAll($search, ''); } return $this->replace($search, ''); } /** * Strip all whitespace characters. This includes tabs and newline characters, * as well as multibyte whitespace such as the thin space and ideographic space. * * EXAMPLE: * s(' Ο συγγραφέας ')->stripWhitespace(); // 'Οσυγγραφέας' * * * @psalm-mutation-free * * @return static */ public function stripWhitespace(): self { return static::create( $this->utf8::strip_whitespace($this->str), $this->encoding ); } /** * Remove css media-queries. * * EXAMPLE: * s('test @media (min-width:660px){ .des-cla #mv-tiles{width:480px} } test ')->stripeCssMediaQueries(); // 'test test ' * * * @psalm-mutation-free * * @return static */ public function stripeCssMediaQueries(): self { return static::create( $this->utf8::css_stripe_media_queries($this->str), $this->encoding ); } /** * Remove empty html-tag. * * EXAMPLE: * s('foo

bar')->stripeEmptyHtmlTags(); // 'foobar' *
* * @psalm-mutation-free * * @return static */ public function stripeEmptyHtmlTags(): self { return static::create( $this->utf8::html_stripe_empty_tags($this->str), $this->encoding ); } /** * Convert the string to StudlyCase. * * EXAMPLE: * * * @psalm-mutation-free * * @return static */ public function studlyCase(): self { $words = \array_map( static function (self $word) { return $word->substr(0, 1) ->toUpperCase() ->appendStringy($word->substr(1)); }, $this->words('', true) ); return new static(\implode('', $words), $this->encoding); } /** * Returns the substring beginning at $start with the specified $length. * It differs from the $this->utf8::substr() function in that providing a $length of * null will return the rest of the string, rather than an empty string. * * EXAMPLE: * * * @param int $start

Position of the first character to use.

* @param int $length [optional]

Maximum number of characters used. Default: null

* * @psalm-mutation-free * * @return static *

Object with its $str being the substring.

*/ public function substr(int $start, int $length = null): self { return static::create( $this->utf8::substr( $this->str, $start, $length, $this->encoding ), $this->encoding ); } /** * Return part of the string. * Alias for substr() * * EXAMPLE: * s('fòôbàř')->substring(2, 3); // 'ôbà' * * * @param int $start

Starting position of the substring.

* @param int $length [optional]

Length of substring.

* * @psalm-mutation-free * * @return static */ public function substring(int $start, int $length = null): self { if ($length === null) { return $this->substr($start); } return $this->substr($start, $length); } /** * Gets the substring after (or before via "$beforeNeedle") the first occurrence of the "$needle". * If no match is found returns new empty Stringy object. * * EXAMPLE: * * * @param string $needle

The string to look for.

* @param bool $beforeNeedle [optional]

Default: false

* * @psalm-mutation-free * * @return static */ public function substringOf(string $needle, bool $beforeNeedle = false): self { return static::create( $this->utf8::str_substr_first( $this->str, $needle, $beforeNeedle, $this->encoding ), $this->encoding ); } /** * Gets the substring after (or before via "$beforeNeedle") the first occurrence of the "$needle". * If no match is found returns new empty Stringy object. * * EXAMPLE: * * * @param string $needle

The string to look for.

* @param bool $beforeNeedle [optional]

Default: false

* * @psalm-mutation-free * * @return static */ public function substringOfIgnoreCase(string $needle, bool $beforeNeedle = false): self { return static::create( $this->utf8::str_isubstr_first( $this->str, $needle, $beforeNeedle, $this->encoding ), $this->encoding ); } /** * Surrounds $str with the given substring. * * EXAMPLE: * s(' ͜ ')->surround('ʘ'); // 'ʘ ͜ ʘ' * * * @param string $substring

The substring to add to both sides.

* * @psalm-mutation-free * * @return static *

Object whose $str had the substring both prepended and appended.

*/ public function surround(string $substring): self { return static::create( $substring . $this->str . $substring, $this->encoding ); } /** * Returns a case swapped version of the string. * * EXAMPLE: * s('Ντανιλ')->swapCase(); // 'νΤΑΝΙΛ' * * * @psalm-mutation-free * * @return static *

Object whose $str has each character's case swapped.

*/ public function swapCase(): self { return static::create( $this->utf8::swapCase($this->str, $this->encoding), $this->encoding ); } /** * Returns a string with smart quotes, ellipsis characters, and dashes from * Windows-1252 (commonly used in Word documents) replaced by their ASCII * equivalents. * * EXAMPLE: * s('“I see…”')->tidy(); // '"I see..."' * * * @psalm-mutation-free * * @return static *

Object whose $str has those characters removed.

*/ public function tidy(): self { return static::create( $this->ascii::normalize_msword($this->str), $this->encoding ); } /** * Returns a trimmed string with the first letter of each word capitalized. * Also accepts an array, $ignore, allowing you to list words not to be * capitalized. * * EXAMPLE: * $ignore = ['at', 'by', 'for', 'in', 'of', 'on', 'out', 'to', 'the']; * s('i like to watch television')->titleize($ignore); // 'I Like to Watch Television' * * * @param string[]|null $ignore [optional]

An array of words not to capitalize or null. * Default: null

* @param string|null $word_define_chars [optional]

An string of chars that will be used as whitespace * separator === words.

* @param string|null $language [optional]

Language of the source string.

* * @psalm-mutation-free * * @return static *

Object with a titleized $str.

*/ public function titleize( array $ignore = null, string $word_define_chars = null, string $language = null ): self { return static::create( $this->utf8::str_titleize( $this->str, $ignore, $this->encoding, false, $language, false, true, $word_define_chars ), $this->encoding ); } /** * Returns a trimmed string in proper title case: Also accepts an array, $ignore, allowing you to list words not to * be capitalized. * * EXAMPLE: * * * Adapted from John Gruber's script. * * @see https://gist.github.com/gruber/9f9e8650d68b13ce4d78 * * @param string[] $ignore

An array of words not to capitalize.

* * @psalm-mutation-free * * @return static *

Object with a titleized $str

*/ public function titleizeForHumans(array $ignore = []): self { return static::create( $this->utf8::str_titleize_for_humans( $this->str, $ignore, $this->encoding ), $this->encoding ); } /** * Returns an ASCII version of the string. A set of non-ASCII characters are * replaced with their closest ASCII counterparts, and the rest are removed * by default. The language or locale of the source string can be supplied * for language-specific transliteration in any of the following formats: * en, en_GB, or en-GB. For example, passing "de" results in "äöü" mapping * to "aeoeue" rather than "aou" as in other languages. * * EXAMPLE: * s('fòôbàř')->toAscii(); // 'foobar' * * * @param string $language [optional]

Language of the source string.

* @param bool $removeUnsupported [optional]

Whether or not to remove the * unsupported characters.

* * @psalm-mutation-free * * @return static *

Object whose $str contains only ASCII characters.

* * @phpstan-param ASCII::*_LANGUAGE_CODE $language */ public function toAscii(string $language = 'en', bool $removeUnsupported = true): self { return static::create( $this->ascii::to_ascii( $this->str, $language, $removeUnsupported ), $this->encoding ); } /** * Returns a boolean representation of the given logical string value. * For example, 'true', '1', 'on' and 'yes' will return true. 'false', '0', * 'off', and 'no' will return false. In all instances, case is ignored. * For other numeric strings, their sign will determine the return value. * In addition, blank strings consisting of only whitespace will return * false. For all other strings, the return value is a result of a * boolean cast. * * EXAMPLE: * s('OFF')->toBoolean(); // false * * * @psalm-mutation-free * * @return bool *

A boolean value for the string.

*/ public function toBoolean(): bool { /** * @psalm-suppress ArgumentTypeCoercion -> maybe the string looks like an int ;) * @phpstan-ignore-next-line */ return $this->utf8::to_boolean($this->str); } /** * Converts all characters in the string to lowercase. * * EXAMPLE: * s('FÒÔBÀŘ')->toLowerCase(); // 'fòôbàř' * * * @param bool $tryToKeepStringLength [optional]

true === try to keep the string length: e.g. ẞ -> ß

* @param string|null $lang [optional]

Set the language for special cases: az, el, lt, tr

* * @psalm-mutation-free * * @return static *

Object with all characters of $str being lowercase.

*/ public function toLowerCase($tryToKeepStringLength = false, $lang = null): self { return static::create( $this->utf8::strtolower( $this->str, $this->encoding, false, $lang, $tryToKeepStringLength ), $this->encoding ); } /** * Converts each tab in the string to some number of spaces, as defined by * $tabLength. By default, each tab is converted to 4 consecutive spaces. * * EXAMPLE: * s(' String speech = "Hi"')->toSpaces(); // ' String speech = "Hi"' * * * @param int $tabLength [optional]

Number of spaces to replace each tab with. Default: 4

* * @psalm-mutation-free * * @return static *

Object whose $str has had tabs switched to spaces.

*/ public function toSpaces(int $tabLength = 4): self { if ($tabLength === 4) { $tab = ' '; } elseif ($tabLength === 2) { $tab = ' '; } else { $tab = \str_repeat(' ', $tabLength); } return static::create( \str_replace("\t", $tab, $this->str), $this->encoding ); } /** * Return Stringy object as string, but you can also use (string) for automatically casting the object into a * string. * * EXAMPLE: * s('fòôbàř')->toString(); // 'fòôbàř' * * * @psalm-mutation-free * * @return string */ public function toString(): string { return (string) $this->str; } /** * Converts each occurrence of some consecutive number of spaces, as * defined by $tabLength, to a tab. By default, each 4 consecutive spaces * are converted to a tab. * * EXAMPLE: * s(' fòô bàř')->toTabs(); // ' fòô bàř' * * * @param int $tabLength [optional]

Number of spaces to replace with a tab. Default: 4

* * @psalm-mutation-free * * @return static *

Object whose $str has had spaces switched to tabs.

*/ public function toTabs(int $tabLength = 4): self { if ($tabLength === 4) { $tab = ' '; } elseif ($tabLength === 2) { $tab = ' '; } else { $tab = \str_repeat(' ', $tabLength); } return static::create( \str_replace($tab, "\t", $this->str), $this->encoding ); } /** * Converts the first character of each word in the string to uppercase * and all other chars to lowercase. * * EXAMPLE: * s('fòô bàř')->toTitleCase(); // 'Fòô Bàř' * * * @psalm-mutation-free * * @return static *

Object with all characters of $str being title-cased.

*/ public function toTitleCase(): self { return static::create( $this->utf8::titlecase($this->str, $this->encoding), $this->encoding ); } /** * Returns an ASCII version of the string. A set of non-ASCII characters are * replaced with their closest ASCII counterparts, and the rest are removed * unless instructed otherwise. * * EXAMPLE: * * * @param bool $strict [optional]

Use "transliterator_transliterate()" from PHP-Intl | WARNING: bad * performance | Default: false

* @param string $unknown [optional]

Character use if character unknown. (default is ?)

* * @psalm-mutation-free * * @return static *

Object whose $str contains only ASCII characters.

*/ public function toTransliterate(bool $strict = false, string $unknown = '?'): self { return static::create( $this->ascii::to_transliterate($this->str, $unknown, $strict), $this->encoding ); } /** * Converts all characters in the string to uppercase. * * EXAMPLE: * s('fòôbàř')->toUpperCase(); // 'FÒÔBÀŘ' * * * @param bool $tryToKeepStringLength [optional]

true === try to keep the string length: e.g. ẞ -> ß

* @param string|null $lang [optional]

Set the language for special cases: az, el, lt, tr

* * @psalm-mutation-free * * @return static *

Object with all characters of $str being uppercase.

*/ public function toUpperCase($tryToKeepStringLength = false, $lang = null): self { return static::create( $this->utf8::strtoupper($this->str, $this->encoding, false, $lang, $tryToKeepStringLength), $this->encoding ); } /** * Returns a string with whitespace removed from the start and end of the * string. Supports the removal of unicode whitespace. Accepts an optional * string of characters to strip instead of the defaults. * * EXAMPLE: * s(' fòôbàř ')->trim(); // 'fòôbàř' * * * @param string $chars [optional]

String of characters to strip. Default: null

* * @psalm-mutation-free * * @return static *

Object with a trimmed $str.

*/ public function trim(string $chars = null): self { return static::create( $this->utf8::trim($this->str, $chars), $this->encoding ); } /** * Returns a string with whitespace removed from the start of the string. * Supports the removal of unicode whitespace. Accepts an optional * string of characters to strip instead of the defaults. * * EXAMPLE: * s(' fòôbàř ')->trimLeft(); // 'fòôbàř ' * * * @param string $chars [optional]

Optional string of characters to strip. Default: null

* * @psalm-mutation-free * * @return static *

Object with a trimmed $str.

*/ public function trimLeft(string $chars = null): self { return static::create( $this->utf8::ltrim($this->str, $chars), $this->encoding ); } /** * Returns a string with whitespace removed from the end of the string. * Supports the removal of unicode whitespace. Accepts an optional * string of characters to strip instead of the defaults. * * EXAMPLE: * s(' fòôbàř ')->trimRight(); // ' fòôbàř' * * * @param string $chars [optional]

Optional string of characters to strip. Default: null

* * @psalm-mutation-free * * @return static *

Object with a trimmed $str.

*/ public function trimRight(string $chars = null): self { return static::create( $this->utf8::rtrim($this->str, $chars), $this->encoding ); } /** * Truncates the string to a given length. If $substring is provided, and * truncating occurs, the string is further truncated so that the substring * may be appended without exceeding the desired length. * * EXAMPLE: * s('What are your plans today?')->truncate(19, '...'); // 'What are your pl...' * * * @param int $length

Desired length of the truncated string.

* @param string $substring [optional]

The substring to append if it can fit. Default: ''

* * @psalm-mutation-free * * @return static *

Object with the resulting $str after truncating.

*/ public function truncate(int $length, string $substring = ''): self { return static::create( $this->utf8::str_truncate($this->str, $length, $substring, $this->encoding), $this->encoding ); } /** * Returns a lowercase and trimmed string separated by underscores. * Underscores are inserted before uppercase characters (with the exception * of the first character of the string), and in place of spaces as well as * dashes. * * EXAMPLE: * s('TestUCase')->underscored(); // 'test_u_case' * * * @psalm-mutation-free * * @return static *

Object with an underscored $str.

*/ public function underscored(): self { return $this->delimit('_'); } /** * Returns an UpperCamelCase version of the supplied string. It trims * surrounding spaces, capitalizes letters following digits, spaces, dashes * and underscores, and removes spaces, dashes, underscores. * * EXAMPLE: * s('Upper Camel-Case')->upperCamelize(); // 'UpperCamelCase' * * * @psalm-mutation-free * * @return static *

Object with $str in UpperCamelCase.

*/ public function upperCamelize(): self { return static::create( $this->utf8::str_upper_camelize($this->str, $this->encoding), $this->encoding ); } /** * Converts the first character of the supplied string to upper case. * * EXAMPLE: * s('σ foo')->upperCaseFirst(); // 'Σ foo' * * * @psalm-mutation-free * * @return static *

Object with the first character of $str being upper case.

*/ public function upperCaseFirst(): self { return static::create($this->utf8::ucfirst($this->str, $this->encoding), $this->encoding); } /** * Simple url-decoding. * * e.g: * 'test+test' => 'test test' * * EXAMPLE: * * * @psalm-mutation-free * * @return static */ public function urlDecode(): self { return static::create(\urldecode($this->str)); } /** * Multi url-decoding + decode HTML entity + fix urlencoded-win1252-chars. * * e.g: * 'test+test' => 'test test' * 'Düsseldorf' => 'Düsseldorf' * 'D%FCsseldorf' => 'Düsseldorf' * 'Düsseldorf' => 'Düsseldorf' * 'D%26%23xFC%3Bsseldorf' => 'Düsseldorf' * 'Düsseldorf' => 'Düsseldorf' * 'D%C3%BCsseldorf' => 'Düsseldorf' * 'D%C3%83%C2%BCsseldorf' => 'Düsseldorf' * 'D%25C3%2583%25C2%25BCsseldorf' => 'Düsseldorf' * * EXAMPLE: * * * @psalm-mutation-free * * @return static */ public function urlDecodeMulti(): self { return static::create($this->utf8::urldecode($this->str)); } /** * Simple url-decoding. * * e.g: * 'test+test' => 'test+test * * EXAMPLE: * * * @psalm-mutation-free * * @return static */ public function urlDecodeRaw(): self { return static::create(\rawurldecode($this->str)); } /** * Multi url-decoding + decode HTML entity + fix urlencoded-win1252-chars. * * e.g: * 'test+test' => 'test+test' * 'Düsseldorf' => 'Düsseldorf' * 'D%FCsseldorf' => 'Düsseldorf' * 'Düsseldorf' => 'Düsseldorf' * 'D%26%23xFC%3Bsseldorf' => 'Düsseldorf' * 'Düsseldorf' => 'Düsseldorf' * 'D%C3%BCsseldorf' => 'Düsseldorf' * 'D%C3%83%C2%BCsseldorf' => 'Düsseldorf' * 'D%25C3%2583%25C2%25BCsseldorf' => 'Düsseldorf' * * EXAMPLE: * * * @psalm-mutation-free * * @return static */ public function urlDecodeRawMulti(): self { return static::create($this->utf8::rawurldecode($this->str)); } /** * Simple url-encoding. * * e.g: * 'test test' => 'test+test' * * EXAMPLE: * * * @psalm-mutation-free * * @return static */ public function urlEncode(): self { return static::create(\urlencode($this->str)); } /** * Simple url-encoding. * * e.g: * 'test test' => 'test%20test' * * EXAMPLE: * * * @psalm-mutation-free * * @return static */ public function urlEncodeRaw(): self { return static::create(\rawurlencode($this->str)); } /** * Converts the string into an URL slug. This includes replacing non-ASCII * characters with their closest ASCII equivalents, removing remaining * non-ASCII and non-alphanumeric characters, and replacing whitespace with * $separator. The separator defaults to a single dash, and the string * is also converted to lowercase. * * EXAMPLE: * s('Using strings like fòô bàř - 1$')->urlify(); // 'using-strings-like-foo-bar-1-dollar' * * * @param string $separator [optional]

The string used to replace whitespace. Default: '-'

* @param string $language [optional]

The language for the url. Default: 'en'

* @param array $replacements [optional]

A map of replaceable strings.

* @param bool $strToLower [optional]

string to lower. Default: true

* * @psalm-mutation-free * * @return static *

Object whose $str has been converted to an URL slug.

* * @psalm-suppress ImpureMethodCall :/ */ public function urlify( string $separator = '-', string $language = 'en', array $replacements = [], bool $strToLower = true ): self { // init $str = $this->str; foreach ($replacements as $from => $to) { $str = \str_replace($from, $to, $str); } return static::create( URLify::slug( $str, $language, $separator, $strToLower ), $this->encoding ); } /** * Converts the string into an valid UTF-8 string. * * EXAMPLE: * s('Düsseldorf')->utf8ify(); // 'Düsseldorf' * * * @psalm-mutation-free * * @return static */ public function utf8ify(): self { return static::create($this->utf8::cleanup($this->str), $this->encoding); } /** * Convert a string into an array of words. * * EXAMPLE: * * * @param string $char_list [optional]

Additional chars for the definition of "words".

* @param bool $remove_empty_values [optional]

Remove empty values.

* @param int|null $remove_short_values [optional]

The min. string length or null to disable

* * @psalm-mutation-free * * @return static[] * * @phpstan-return array */ public function words( string $char_list = '', bool $remove_empty_values = false, int $remove_short_values = null ): array { if ($remove_short_values === null) { $strings = $this->utf8::str_to_words( $this->str, $char_list, $remove_empty_values ); } else { $strings = $this->utf8::str_to_words( $this->str, $char_list, $remove_empty_values, $remove_short_values ); } /** @noinspection AlterInForeachInspection */ foreach ($strings as &$string) { $string = static::create($string); } /** @noinspection PhpSillyAssignmentInspection */ /** @var static[] $strings */ $strings = $strings; return $strings; } /** * Convert a string into an collection of words. * * EXAMPLE: * S::create('中文空白 oöäü#s')->wordsCollection('#', true)->toStrings(); // ['中文空白', 'oöäü#s'] * * * @param string $char_list [optional]

Additional chars for the definition of "words".

* @param bool $remove_empty_values [optional]

Remove empty values.

* @param int|null $remove_short_values [optional]

The min. string length or null to disable

* * @psalm-mutation-free * * @return CollectionStringy|static[] *

An collection of Stringy objects.

* * @phpstan-return CollectionStringy */ public function wordsCollection( string $char_list = '', bool $remove_empty_values = false, int $remove_short_values = null ): CollectionStringy { /** * @psalm-suppress ImpureMethodCall -> add more psalm stuff to the collection class */ return CollectionStringy::create( $this->words( $char_list, $remove_empty_values, $remove_short_values ) ); } /** * Surrounds $str with the given substring. * * EXAMPLE: * * * @param string $substring

The substring to add to both sides.

* * @psalm-mutation-free * * @return static *

Object whose $str had the substring both prepended and appended.

*/ public function wrap(string $substring): self { return $this->surround($substring); } /** * Returns the replacements for the toAscii() method. * * @psalm-mutation-free * * @return array> *

An array of replacements.

* * @deprecated this is only here for backward-compatibly reasons */ protected function charsArray(): array { return $this->ascii::charsArrayWithMultiLanguageValues(); } /** * Returns true if $str matches the supplied pattern, false otherwise. * * @param string $pattern

Regex pattern to match against.

* * @psalm-mutation-free * * @return bool *

Whether or not $str matches the pattern.

*/ protected function matchesPattern(string $pattern): bool { return $this->utf8::str_matches_pattern($this->str, $pattern); } }