Skip to content

Commit 4206bfa

Browse files
authored
Add methods isAscii, headline, position, take, toBase64 and unwrap in the Str and Stringable. (#6692)
1 parent 4997554 commit 4206bfa

File tree

4 files changed

+451
-40
lines changed

4 files changed

+451
-40
lines changed

src/Str.php

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,18 @@ public static function is($pattern, $value)
356356
return false;
357357
}
358358

359+
/**
360+
* Determine if a given string is 7 bit ASCII.
361+
*/
362+
public static function isAscii(string $value): bool
363+
{
364+
if ($value == '') {
365+
return true;
366+
}
367+
368+
return ! preg_match('/[^\x09\x0A\x0D\x20-\x7E]/', $value);
369+
}
370+
359371
/**
360372
* Convert a string to kebab case.
361373
*
@@ -552,6 +564,14 @@ public static function plural(string $value, int $count = 2): string
552564
return Pluralizer::plural($value, $count);
553565
}
554566

567+
/**
568+
* Find the multi-byte safe position of the first occurrence of a given substring in a string.
569+
*/
570+
public static function position(string $haystack, string $needle, int $offset = 0, ?string $encoding = null): false|int
571+
{
572+
return mb_strpos($haystack, (string) $needle, $offset, $encoding);
573+
}
574+
555575
/**
556576
* Generate a more truly "random" alpha-numeric string.
557577
*/
@@ -582,6 +602,8 @@ public static function repeat(string $string, int $times)
582602

583603
/**
584604
* Replace a given value in the string sequentially with an array.
605+
*
606+
* @param string[] $replace
585607
*/
586608
public static function replaceArray(string $search, array $replace, string $subject): string
587609
{
@@ -692,6 +714,22 @@ public static function title(string $value): string
692714
return mb_convert_case($value, MB_CASE_TITLE, 'UTF-8');
693715
}
694716

717+
/**
718+
* Convert the given string to proper case for each word.
719+
*/
720+
public static function headline(string $value): string
721+
{
722+
$parts = explode(' ', $value);
723+
724+
$parts = count($parts) > 1
725+
? array_map([static::class, 'title'], $parts)
726+
: array_map([static::class, 'title'], static::ucsplit(implode('_', $parts)));
727+
728+
$collapsed = static::replace(['-', '_', ' '], '_', implode('_', $parts));
729+
730+
return implode(' ', array_filter(explode('_', $collapsed)));
731+
}
732+
695733
/**
696734
* Get the singular form of an English word.
697735
*/
@@ -813,6 +851,7 @@ public static function ucfirst(string $string): string
813851
*
814852
* @param int $offset if is negative it starts from the end
815853
* @param string $replacement default is *
854+
* @return string
816855
*/
817856
public static function mask(string $string, int $offset = 0, int $length = 0, string $replacement = '*')
818857
{
@@ -857,6 +896,9 @@ public static function isUlid($value): bool
857896
return $value[0] <= '7';
858897
}
859898

899+
/**
900+
* Generate a ULID.
901+
*/
860902
public static function ulid(?DateTimeInterface $time = null): Ulid
861903
{
862904
if (! class_exists(Ulid::class)) {
@@ -866,6 +908,11 @@ public static function ulid(?DateTimeInterface $time = null): Ulid
866908
return new Ulid(Ulid::generate($time));
867909
}
868910

911+
/**
912+
* Determine if a given value is a valid URL.
913+
*
914+
* @param string $value
915+
*/
869916
public static function isUrl($value, array $protocols = []): bool
870917
{
871918
if (! is_string($value)) {
@@ -916,6 +963,9 @@ public static function isUuid($value): bool
916963
return preg_match('/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iD', $value) > 0;
917964
}
918965

966+
/**
967+
* Generate a UUID (version 4).
968+
*/
919969
public static function uuid(): UuidInterface
920970
{
921971
if (! class_exists(Uuid::class)) {
@@ -925,6 +975,9 @@ public static function uuid(): UuidInterface
925975
return Uuid::uuid4();
926976
}
927977

978+
/**
979+
* Generate a time-ordered UUID.
980+
*/
928981
public static function orderedUuid(?DateTimeInterface $time = null): UuidInterface
929982
{
930983
if (! class_exists(Uuid::class)) {
@@ -934,6 +987,14 @@ public static function orderedUuid(?DateTimeInterface $time = null): UuidInterfa
934987
return Uuid::uuid7($time);
935988
}
936989

990+
/**
991+
* Get the smallest possible portion of a string between two given values.
992+
*
993+
* @param string $subject
994+
* @param string $from
995+
* @param string $to
996+
* @return string
997+
*/
937998
public static function betweenFirst($subject, $from, $to)
938999
{
9391000
if ($from === '' || $to === '') {
@@ -943,6 +1004,9 @@ public static function betweenFirst($subject, $from, $to)
9431004
return Str::before(Str::after($subject, $from), $to);
9441005
}
9451006

1007+
/**
1008+
* @param string $value
1009+
*/
9461010
public static function classNamespace($value): string
9471011
{
9481012
if ($pos = strrpos($value, '\\')) {
@@ -952,11 +1016,22 @@ public static function classNamespace($value): string
9521016
return '';
9531017
}
9541018

1019+
/**
1020+
* Convert the case of a string.
1021+
*/
9551022
public static function convertCase(string $string, int $mode = MB_CASE_FOLD, ?string $encoding = 'UTF-8'): string
9561023
{
9571024
return mb_convert_case($string, $mode, $encoding);
9581025
}
9591026

1027+
/**
1028+
* Extracts an excerpt from text that matches the first instance of a phrase.
1029+
*
1030+
* @param string $text
1031+
* @param string $phrase
1032+
* @param array $options
1033+
* @return null|string
1034+
*/
9601035
public static function excerpt($text, $phrase = '', $options = [])
9611036
{
9621037
$radius = $options['radius'] ?? 100;
@@ -985,6 +1060,11 @@ public static function excerpt($text, $phrase = '', $options = [])
9851060
return $start->append($matches[2], $end)->__toString();
9861061
}
9871062

1063+
/**
1064+
* Determine if a given value is valid JSON.
1065+
*
1066+
* @param mixed $value
1067+
*/
9881068
public static function isJson($value): bool
9891069
{
9901070
if (! is_string($value)) {
@@ -1004,11 +1084,26 @@ public static function isJson($value): bool
10041084
return true;
10051085
}
10061086

1087+
/**
1088+
* Make a string's first character lowercase.
1089+
*
1090+
* @param string $string
1091+
*/
10071092
public static function lcfirst($string): string
10081093
{
10091094
return Str::lower(Str::substr($string, 0, 1)) . Str::substr($string, 1);
10101095
}
10111096

1097+
/**
1098+
* Generate a random, secure password.
1099+
*
1100+
* @param int $length
1101+
* @param bool $letters
1102+
* @param bool $numbers
1103+
* @param bool $symbols
1104+
* @param bool $spaces
1105+
* @return string
1106+
*/
10121107
public static function password($length = 32, $letters = true, $numbers = true, $symbols = true, $spaces = false)
10131108
{
10141109
return (new Collection())
@@ -1032,6 +1127,14 @@ public static function password($length = 32, $letters = true, $numbers = true,
10321127
->implode('');
10331128
}
10341129

1130+
/**
1131+
* Replace the first occurrence of the given value if it appears at the start of the string.
1132+
*
1133+
* @param string $search
1134+
* @param string $replace
1135+
* @param string $subject
1136+
* @return string
1137+
*/
10351138
public static function replaceStart($search, $replace, $subject)
10361139
{
10371140
$search = (string) $search;
@@ -1047,6 +1150,14 @@ public static function replaceStart($search, $replace, $subject)
10471150
return $subject;
10481151
}
10491152

1153+
/**
1154+
* Replace the last occurrence of a given value if it appears at the end of the string.
1155+
*
1156+
* @param string $search
1157+
* @param string $replace
1158+
* @param string $subject
1159+
* @return string
1160+
*/
10501161
public static function replaceEnd($search, $replace, $subject)
10511162
{
10521163
$search = (string) $search;
@@ -1080,6 +1191,9 @@ public static function replaceMatches($pattern, $replace, $subject, $limit = -1)
10801191
return preg_replace($pattern, $replace, $subject, $limit);
10811192
}
10821193

1194+
/**
1195+
* @param string $value
1196+
*/
10831197
public static function reverse($value): string
10841198
{
10851199
return implode(array_reverse(mb_str_split($value)));
@@ -1133,11 +1247,25 @@ public static function rtrim($value, $charlist = null)
11331247
return rtrim($value, $charlist);
11341248
}
11351249

1250+
/**
1251+
* Remove all "extra" blank space from the given string.
1252+
*
1253+
* @param string $value
1254+
*/
11361255
public static function squish($value): null|array|string
11371256
{
11381257
return preg_replace('~(\s|\x{3164}|\x{1160})+~u', ' ', static::trim($value));
11391258
}
11401259

1260+
/**
1261+
* Replace text within a portion of a string.
1262+
*
1263+
* @param string|string[] $string
1264+
* @param string|string[] $replace
1265+
* @param int|int[] $offset
1266+
* @param null|int|int[] $length
1267+
* @return string|string[]
1268+
*/
11411269
public static function substrReplace($string, $replace, $offset = 0, $length = null): array|string
11421270
{
11431271
if ($length === null) {
@@ -1147,26 +1275,100 @@ public static function substrReplace($string, $replace, $offset = 0, $length = n
11471275
return substr_replace($string, $replace, $offset, $length);
11481276
}
11491277

1278+
/**
1279+
* Swap multiple keywords in a string with other keywords.
1280+
*
1281+
* @param string $subject
1282+
* @return string
1283+
*/
11501284
public static function swap(array $map, $subject): array|string
11511285
{
11521286
return str_replace(array_keys($map), array_values($map), $subject);
11531287
}
11541288

1289+
/**
1290+
* Take the first or last {$limit} characters of a string.
1291+
*/
1292+
public static function take(string $string, int $limit): string
1293+
{
1294+
if ($limit < 0) {
1295+
return static::substr($string, $limit);
1296+
}
1297+
1298+
return static::substr($string, 0, $limit);
1299+
}
1300+
1301+
/**
1302+
* Convert the given string to Base64 encoding.
1303+
*
1304+
* @param string $string
1305+
*/
1306+
public static function toBase64($string): string
1307+
{
1308+
return base64_encode($string);
1309+
}
1310+
1311+
/**
1312+
* Split a string into pieces by uppercase characters.
1313+
*
1314+
* @param string $string
1315+
* @return bool|string[]
1316+
*/
11551317
public static function ucsplit($string): array|bool
11561318
{
11571319
return preg_split('/(?=\p{Lu})/u', $string, -1, PREG_SPLIT_NO_EMPTY);
11581320
}
11591321

1322+
/**
1323+
* Unwrap the string with the given strings.
1324+
*
1325+
* @param string $value
1326+
* @param string $before
1327+
* @param null|string $after
1328+
*/
1329+
public static function unwrap($value, $before, $after = null): string
1330+
{
1331+
if (static::startsWith($value, $before)) {
1332+
$value = static::substr($value, static::length($before));
1333+
}
1334+
1335+
if (static::endsWith($value, $after ??= $before)) {
1336+
$value = static::substr($value, 0, -static::length($after));
1337+
}
1338+
1339+
return $value;
1340+
}
1341+
1342+
/**
1343+
* Get the number of words a string contains.
1344+
*
1345+
* @param string $string
1346+
*/
11601347
public static function wordCount($string): array|int
11611348
{
11621349
return str_word_count($string);
11631350
}
11641351

1352+
/**
1353+
* Wrap the string with the given strings.
1354+
*
1355+
* @param string $value
1356+
* @param string $before
1357+
* @param null|string $after
1358+
*/
11651359
public static function wrap($value, $before, $after = null): string
11661360
{
11671361
return $before . $value . ($after ??= $before);
11681362
}
11691363

1364+
/**
1365+
* Wrap a string to a given number of characters.
1366+
*
1367+
* @param string $string
1368+
* @param int $characters
1369+
* @param string $break
1370+
* @param bool $cutLongWords
1371+
*/
11701372
public static function wordWrap($string, $characters = 75, $break = "\n", $cutLongWords = false): string
11711373
{
11721374
return wordwrap($string, $characters, $break, $cutLongWords);

0 commit comments

Comments
 (0)