diff --git a/src/Illuminate/Support/Str.php b/src/Illuminate/Support/Str.php index 6c377897dcf7..cd4faf924123 100644 --- a/src/Illuminate/Support/Str.php +++ b/src/Illuminate/Support/Str.php @@ -730,17 +730,15 @@ public static function title($value) */ public static function headline($value) { - $parts = explode('_', static::replace(' ', '_', $value)); + $parts = explode(' ', $value); - if (count($parts) > 1) { - $parts = array_map([static::class, 'title'], $parts); - } - - $studly = static::studly(implode($parts)); + $parts = count($parts) > 1 + ? $parts = array_map([static::class, 'title'], $parts) + : $parts = array_map([static::class, 'title'], static::ucsplit(implode('_', $parts))); - $words = preg_split('/(?=[A-Z])/', $studly, -1, PREG_SPLIT_NO_EMPTY); + $collapsed = static::replace(['-', '_', ' '], '_', implode('_', $parts)); - return implode(' ', $words); + return implode(' ', array_filter(explode('_', $collapsed))); } /** @@ -839,9 +837,13 @@ public static function studly($value) return static::$studlyCache[$key]; } - $value = ucwords(str_replace(['-', '_'], ' ', $value)); + $words = explode(' ', static::replace(['-', '_'], ' ', $value)); + + $studlyWords = array_map(function ($word) { + return static::ucfirst($word); + }, $words); - return static::$studlyCache[$key] = str_replace(' ', '', $value); + return static::$studlyCache[$key] = implode($studlyWords); } /** @@ -904,6 +906,17 @@ public static function ucfirst($string) return static::upper(static::substr($string, 0, 1)).static::substr($string, 1); } + /** + * Split a string into pieces by uppercase characters. + * + * @param string $string + * @return array + */ + public static function ucsplit($string) + { + return preg_split('/(?=\p{Lu})/u', $string, -1, PREG_SPLIT_NO_EMPTY); + } + /** * Get the number of words a string contains. * diff --git a/src/Illuminate/Support/Stringable.php b/src/Illuminate/Support/Stringable.php index da27137d3c2e..5507bd6308b5 100644 --- a/src/Illuminate/Support/Stringable.php +++ b/src/Illuminate/Support/Stringable.php @@ -776,6 +776,16 @@ public function ucfirst() return new static(Str::ucfirst($this->value)); } + /** + * Split a string by uppercase characters. + * + * @return static + */ + public function ucsplit() + { + return new static(Str::ucsplit($this->value)); + } + /** * Execute the given callback if the string contains a given substring. * diff --git a/tests/Support/SupportStrTest.php b/tests/Support/SupportStrTest.php index de2e60349d00..9d644fa8a2e6 100755 --- a/tests/Support/SupportStrTest.php +++ b/tests/Support/SupportStrTest.php @@ -52,6 +52,17 @@ public function testStringHeadline() $this->assertSame('Foo Bar', Str::headline('foo_bar')); $this->assertSame('Foo Bar Baz', Str::headline('foo-barBaz')); $this->assertSame('Foo Bar Baz', Str::headline('foo-bar_baz')); + + $this->assertSame('Öffentliche Überraschungen', Str::headline('öffentliche-überraschungen')); + $this->assertSame('Öffentliche Überraschungen', Str::headline('-_öffentliche_überraschungen_-')); + $this->assertSame('Öffentliche Überraschungen', Str::headline('-öffentliche überraschungen')); + + $this->assertSame('Sind Öde Und So', Str::headline('sindÖdeUndSo')); + + $this->assertSame('Orwell 1984', Str::headline('orwell 1984')); + $this->assertSame('Orwell 1984', Str::headline('orwell 1984')); + $this->assertSame('Orwell 1984', Str::headline('-orwell-1984 -')); + $this->assertSame('Orwell 1984', Str::headline(' orwell_- 1984 ')); } public function testStringWithoutWordsDoesntProduceError() @@ -456,6 +467,8 @@ public function testStudly() $this->assertSame('FooBar', Str::studly('foo_bar')); // test cache $this->assertSame('FooBarBaz', Str::studly('foo-barBaz')); $this->assertSame('FooBarBaz', Str::studly('foo-bar_baz')); + + $this->assertSame('ÖffentlicheÜberraschungen', Str::studly('öffentliche-überraschungen')); } public function testMask() @@ -550,6 +563,18 @@ public function testUcfirst() $this->assertSame('Мама мыла раму', Str::ucfirst('мама мыла раму')); } + public function testUcsplit() + { + $this->assertSame(['Laravel_p_h_p_framework'], Str::ucsplit('Laravel_p_h_p_framework')); + $this->assertSame(['Laravel_', 'P_h_p_framework'], Str::ucsplit('Laravel_P_h_p_framework')); + $this->assertSame(['laravel', 'P', 'H', 'P', 'Framework'], Str::ucsplit('laravelPHPFramework')); + $this->assertSame(['Laravel-ph', 'P-framework'], Str::ucsplit('Laravel-phP-framework')); + + $this->assertSame(['Żółta', 'Łódka'], Str::ucsplit('ŻółtaŁódka')); + $this->assertSame(['sind', 'Öde', 'Und', 'So'], Str::ucsplit('sindÖdeUndSo')); + $this->assertSame(['Öffentliche', 'Überraschungen'], Str::ucsplit('ÖffentlicheÜberraschungen')); + } + public function testUuid() { $this->assertInstanceOf(UuidInterface::class, Str::uuid());