Files
yusheng-php/addons/epay/library/hyperf/utils/src/Str.php
2025-08-07 20:21:47 +08:00

1321 lines
34 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
declare(strict_types=1);
/**
* This file is part of Hyperf.
*
* @link https://www.hyperf.io
* @document https://hyperf.wiki
* @contact group@hyperf.io
* @license https://github.com/hyperf/hyperf/blob/master/LICENSE
*/
namespace Hyperf\Utils;
use Hyperf\Macroable\Macroable;
use Hyperf\Utils\Exception\InvalidArgumentException;
/**
* Most of the methods in this file come from illuminate/support,
* thanks Laravel Team provide such a useful class.
*/
class Str
{
use Macroable;
/**
* The cache of snake-cased words.
*
* @var array
*/
protected static $snakeCache = [];
/**
* The cache of camel-cased words.
*
* @var array
*/
protected static $camelCache = [];
/**
* The cache of studly-cased words.
*
* @var array
*/
protected static $studlyCache = [];
/**
* Get a new stringable object from the given string.
*
* @param string $string
* @return Stringable
*/
public static function of($string)
{
return new Stringable($string);
}
/**
* Return the remainder of a string after a given value.
*
* @param string $subject
* @param string $search
* @return string
*/
public static function after($subject, $search)
{
return $search === '' ? $subject : array_reverse(explode($search, $subject, 2))[0];
}
/**
* Return the remainder of a string after the last occurrence of a given value.
*
* @param string $subject
* @param string $search
* @return string
*/
public static function afterLast($subject, $search)
{
if ($search === '') {
return $subject;
}
$position = strrpos($subject, (string) $search);
if ($position === false) {
return $subject;
}
return substr($subject, $position + strlen($search));
}
/**
* Transliterate a UTF-8 value to ASCII.
*
* @param string $value
* @param string $language
* @return string
*/
public static function ascii($value, $language = 'en')
{
$languageSpecific = static::languageSpecificCharsArray($language);
if (! is_null($languageSpecific)) {
$value = str_replace($languageSpecific[0], $languageSpecific[1], $value);
}
foreach (static::charsArray() as $key => $val) {
$value = str_replace($val, (string) $key, $value);
}
return preg_replace('/[^\x20-\x7E]/u', '', $value);
}
/**
* Get the portion of a string before a given value.
*
* @param string $subject
* @param string $search
* @return string
*/
public static function before($subject, $search)
{
return $search === '' ? $subject : explode($search, $subject)[0];
}
/**
* Get the portion of a string before the last occurrence of a given value.
*
* @param string $subject
* @param string $search
* @return string
*/
public static function beforeLast($subject, $search)
{
if ($search === '') {
return $subject;
}
$pos = mb_strrpos($subject, $search);
if ($pos === false) {
return $subject;
}
return static::substr($subject, 0, $pos);
}
/**
* Get the portion of a string between two given values.
*
* @param string $subject
* @param string $from
* @param string $to
* @return string
*/
public static function between($subject, $from, $to)
{
if ($from === '' || $to === '') {
return $subject;
}
return static::beforeLast(static::after($subject, $from), $to);
}
/**
* Convert a value to camel case.
*
* @param string $value
* @return string
*/
public static function camel($value)
{
if (isset(static::$camelCache[$value])) {
return static::$camelCache[$value];
}
return static::$camelCache[$value] = lcfirst(static::studly($value));
}
/**
* Determine if a given string contains a given substring.
*
* @param string $haystack
* @param array|string $needles
* @return bool
*/
public static function contains($haystack, $needles)
{
foreach ((array) $needles as $needle) {
if ($needle !== '' && mb_strpos($haystack, $needle) !== false) {
return true;
}
}
return false;
}
/**
* Determine if a given string contains all array values.
*
* @param string $haystack
* @param string[] $needles
* @return bool
*/
public static function containsAll($haystack, array $needles)
{
foreach ($needles as $needle) {
if (! static::contains($haystack, $needle)) {
return false;
}
}
return true;
}
/**
* Determine if a given string ends with a given substring.
*
* @param string $haystack
* @param array|string $needles
* @return bool
*/
public static function endsWith($haystack, $needles)
{
foreach ((array) $needles as $needle) {
if (substr($haystack, -strlen($needle)) === (string) $needle) {
return true;
}
}
return false;
}
/**
* Cap a string with a single instance of a given value.
*
* @param string $value
* @param string $cap
* @return string
*/
public static function finish($value, $cap)
{
$quoted = preg_quote($cap, '/');
return preg_replace('/(?:' . $quoted . ')+$/u', '', $value) . $cap;
}
/**
* Determine if a given string matches a given pattern.
*
* @param array|string $pattern
* @param string $value
* @return bool
*/
public static function is($pattern, $value)
{
$patterns = Arr::wrap($pattern);
if (empty($patterns)) {
return false;
}
foreach ($patterns as $pattern) {
// If the given value is an exact match we can of course return true right
// from the beginning. Otherwise, we will translate asterisks and do an
// actual pattern match against the two strings to see if they match.
if ($pattern == $value) {
return true;
}
$pattern = preg_quote($pattern, '#');
// Asterisks are translated into zero-or-more regular expression wildcards
// to make it convenient to check if the strings starts with the given
// pattern such as "library/*", making any string check convenient.
$pattern = str_replace('\*', '.*', $pattern);
if (preg_match('#^' . $pattern . '\z#u', $value) === 1) {
return true;
}
}
return false;
}
/**
* Convert a string to kebab case.
*
* @param string $value
* @return string
*/
public static function kebab($value)
{
return static::snake($value, '-');
}
/**
* Return the length of the given string.
*
* @param string $value
* @param string $encoding
* @return int
*/
public static function length($value, $encoding = null)
{
if ($encoding) {
return mb_strlen($value, $encoding);
}
return mb_strlen($value);
}
/**
* Limit the number of characters in a string.
*
* @param string $value
* @param int $limit
* @param string $end
* @return string
*/
public static function limit($value, $limit = 100, $end = '...')
{
if (mb_strwidth($value, 'UTF-8') <= $limit) {
return $value;
}
return rtrim(mb_strimwidth($value, 0, $limit, '', 'UTF-8')) . $end;
}
/**
* Convert the given string to lower-case.
*
* @param string $value
* @return string
*/
public static function lower($value)
{
return mb_strtolower($value, 'UTF-8');
}
/**
* Limit the number of words in a string.
*/
public static function words(string $value, int $words = 100, string $end = '...'): string
{
preg_match('/^\s*+(?:\S++\s*+){1,' . $words . '}/u', $value, $matches);
if (! isset($matches[0]) || static::length($value) === static::length($matches[0])) {
return $value;
}
return rtrim($matches[0]) . $end;
}
/**
* Get the string matching the given pattern.
*
* @param string $pattern
* @param string $subject
* @return string
*/
public static function match($pattern, $subject)
{
preg_match($pattern, $subject, $matches);
if (! $matches) {
return '';
}
return $matches[1] ?? $matches[0];
}
/**
* Get the string matching the given pattern.
*
* @param string $pattern
* @param string $subject
* @return Collection
*/
public static function matchAll($pattern, $subject)
{
preg_match_all($pattern, $subject, $matches);
if (empty($matches[0])) {
return collect();
}
return collect($matches[1] ?? $matches[0]);
}
/**
* Pad both sides of a string with another.
*
* @param string $value
* @param int $length
* @param string $pad
* @return string
*/
public static function padBoth($value, $length, $pad = ' ')
{
return str_pad($value, $length, $pad, STR_PAD_BOTH);
}
/**
* Pad the left side of a string with another.
*
* @param string $value
* @param int $length
* @param string $pad
* @return string
*/
public static function padLeft($value, $length, $pad = ' ')
{
return str_pad($value, $length, $pad, STR_PAD_LEFT);
}
/**
* Pad the right side of a string with another.
*
* @param string $value
* @param int $length
* @param string $pad
* @return string
*/
public static function padRight($value, $length, $pad = ' ')
{
return str_pad($value, $length, $pad, STR_PAD_RIGHT);
}
/**
* Parse a Class@method style callback into class and method.
*
* @param null|string $default
*/
public static function parseCallback(string $callback, $default = null): array
{
return static::contains($callback, '@') ? explode('@', $callback, 2) : [$callback, $default];
}
/**
* Pluralize the last word of an English, studly caps case string.
*/
public static function pluralStudly(string $value, int $count = 2): string
{
$parts = preg_split('/(.)(?=[A-Z])/u', $value, -1, PREG_SPLIT_DELIM_CAPTURE);
$lastWord = array_pop($parts);
return implode('', $parts) . self::plural($lastWord, $count);
}
/**
* Get the plural form of an English word.
*/
public static function plural(string $value, int $count = 2): string
{
return Pluralizer::plural($value, $count);
}
/**
* Generate a more truly "random" alpha-numeric string.
*/
public static function random(int $length = 16): string
{
$string = '';
while (($len = strlen($string)) < $length) {
$size = $length - $len;
$bytes = random_bytes($size);
$string .= substr(str_replace(['/', '+', '='], '', base64_encode($bytes)), 0, $size);
}
return $string;
}
/**
* Repeat the given string.
*
* @return string
*/
public static function repeat(string $string, int $times)
{
return str_repeat($string, $times);
}
/**
* Replace a given value in the string sequentially with an array.
*/
public static function replaceArray(string $search, array $replace, string $subject): string
{
foreach ($replace as $value) {
$subject = static::replaceFirst($search, (string) $value, $subject);
}
return $subject;
}
/**
* Replace the given value in the given string.
*
* @param string|string[] $search
* @param string|string[] $replace
* @param string|string[] $subject
* @return string
*/
public static function replace($search, $replace, $subject)
{
return str_replace($search, $replace, $subject);
}
/**
* Replace the first occurrence of a given value in the string.
*/
public static function replaceFirst(string $search, string $replace, string $subject): string
{
if ($search == '') {
return $subject;
}
$position = strpos($subject, $search);
if ($position !== false) {
return substr_replace($subject, $replace, $position, strlen($search));
}
return $subject;
}
/**
* Replace the last occurrence of a given value in the string.
*/
public static function replaceLast(string $search, string $replace, string $subject): string
{
$position = strrpos($subject, $search);
if ($position !== false) {
return substr_replace($subject, $replace, $position, strlen($search));
}
return $subject;
}
/**
* Remove any occurrence of the given string in the subject.
*
* @param array<string>|string $search
* @param string $subject
* @param bool $caseSensitive
* @return string
*/
public static function remove($search, $subject, $caseSensitive = true)
{
return $caseSensitive
? str_replace($search, '', $subject)
: str_ireplace($search, '', $subject);
}
/**
* Begin a string with a single instance of a given value.
*/
public static function start(string $value, string $prefix): string
{
$quoted = preg_quote($prefix, '/');
return $prefix . preg_replace('/^(?:' . $quoted . ')+/u', '', $value);
}
/**
* Strip HTML and PHP tags from the given string.
*
* @param null|string|string[] $allowedTags
*/
public static function stripTags(string $value, $allowedTags = null): string
{
return strip_tags($value, $allowedTags);
}
/**
* Convert the given string to upper-case.
*/
public static function upper(string $value): string
{
return mb_strtoupper($value, 'UTF-8');
}
/**
* Convert the given string to title case.
*/
public static function title(string $value): string
{
return mb_convert_case($value, MB_CASE_TITLE, 'UTF-8');
}
/**
* Get the singular form of an English word.
*/
public static function singular(string $value): string
{
return Pluralizer::singular($value);
}
/**
* Generate a URL friendly "slug" from a given string.
*/
public static function slug(string $title, string $separator = '-', string $language = 'en'): string
{
$title = $language ? static::ascii($title, $language) : $title;
// Convert all dashes/underscores into separator
$flip = $separator === '-' ? '_' : '-';
$title = preg_replace('![' . preg_quote($flip) . ']+!u', $separator, $title);
// Replace @ with the word 'at'
$title = str_replace('@', $separator . 'at' . $separator, $title);
// Remove all characters that are not the separator, letters, numbers, or whitespace.
$title = preg_replace('![^' . preg_quote($separator) . '\pL\pN\s]+!u', '', mb_strtolower($title));
// Replace all separator characters and whitespace by a single separator
$title = preg_replace('![' . preg_quote($separator) . '\s]+!u', $separator, $title);
return trim($title, $separator);
}
/**
* Convert a string to snake case.
*/
public static function snake(string $value, string $delimiter = '_'): string
{
$key = $value;
if (isset(static::$snakeCache[$key][$delimiter])) {
return static::$snakeCache[$key][$delimiter];
}
if (! ctype_lower($value)) {
$value = preg_replace('/\s+/u', '', ucwords($value));
$value = static::lower(preg_replace('/(.)(?=[A-Z])/u', '$1' . $delimiter, $value));
}
return static::$snakeCache[$key][$delimiter] = $value;
}
/**
* Determine if a given string starts with a given substring.
*
* @param array|string $needles
*/
public static function startsWith(string $haystack, $needles): bool
{
foreach ((array) $needles as $needle) {
if ($needle !== '' && substr($haystack, 0, strlen($needle)) === (string) $needle) {
return true;
}
}
return false;
}
/**
* Convert a value to studly caps case.
*/
public static function studly(string $value, string $gap = ''): string
{
$key = $value;
if (isset(static::$studlyCache[$key])) {
return static::$studlyCache[$key];
}
$value = ucwords(str_replace(['-', '_'], ' ', $value));
return static::$studlyCache[$key] = str_replace(' ', $gap, $value);
}
/**
* Returns the portion of string specified by the start and length parameters.
*
* @param string $string
* @param int $start
* @param null|int $length
* @return string
*/
public static function substr($string, $start, $length = null)
{
return mb_substr($string, $start, $length, 'UTF-8');
}
/**
* Returns the number of substring occurrences.
*
* @param string $haystack
* @param string $needle
* @param int $offset
* @param null|int $length
* @return int
*/
public static function substrCount($haystack, $needle, $offset = 0, $length = null)
{
if (! is_null($length)) {
return substr_count($haystack, $needle, $offset, $length);
}
return substr_count($haystack, $needle, $offset);
}
/**
* Make a string's first character uppercase.
*/
public static function ucfirst(string $string): string
{
return static::upper(static::substr($string, 0, 1)) . static::substr($string, 1);
}
/**
* Replaces the first or the last ones chars from a string by a given char.
*
* @param int $offset if is negative it starts from the end
* @param string $replacement default is *
*/
public static function mask(string $string, int $offset = 0, int $length = 0, string $replacement = '*')
{
if ($length < 0) {
throw new InvalidArgumentException('The length must equal or greater than zero.');
}
$stringLength = mb_strlen($string);
$absOffset = abs($offset);
if ($absOffset >= $stringLength) {
return $string;
}
$hiddenLength = $length ?: $stringLength - $absOffset;
if ($offset >= 0) {
return mb_substr($string, 0, $offset) . str_repeat($replacement, $hiddenLength) . mb_substr($string, $offset + $hiddenLength);
}
return mb_substr($string, 0, max($stringLength - $hiddenLength - $absOffset, 0)) . str_repeat($replacement, $hiddenLength) . mb_substr($string, $offset);
}
/**
* Returns the replacements for the ascii method.
* Note: Adapted from Stringy\Stringy.
*
* @see https://github.com/danielstjules/Stringy/blob/3.1.0/LICENSE.txt
*/
protected static function charsArray(): array
{
static $charsArray;
if (isset($charsArray)) {
return $charsArray;
}
return $charsArray = [
'0' => ['°', '₀', '۰', ''],
'1' => ['¹', '₁', '۱', ''],
'2' => ['²', '₂', '۲', ''],
'3' => ['³', '₃', '۳', ''],
'4' => ['⁴', '₄', '۴', '٤', ''],
'5' => ['⁵', '₅', '۵', '٥', ''],
'6' => ['⁶', '₆', '۶', '٦', ''],
'7' => ['⁷', '₇', '۷', ''],
'8' => ['⁸', '₈', '۸', ''],
'9' => ['⁹', '₉', '۹', ''],
'a' => [
'à',
'á',
'ả',
'ã',
'ạ',
'ă',
'ắ',
'ằ',
'ẳ',
'ẵ',
'ặ',
'â',
'ấ',
'ầ',
'ẩ',
'ẫ',
'ậ',
'ā',
'ą',
'å',
'α',
'ά',
'ἀ',
'ἁ',
'ἂ',
'ἃ',
'ἄ',
'ἅ',
'ἆ',
'ἇ',
'ᾀ',
'ᾁ',
'ᾂ',
'ᾃ',
'ᾄ',
'ᾅ',
'ᾆ',
'ᾇ',
'ὰ',
'ά',
'ᾰ',
'ᾱ',
'ᾲ',
'ᾳ',
'ᾴ',
'ᾶ',
'ᾷ',
'а',
'أ',
'အ',
'ာ',
'ါ',
'ǻ',
'ǎ',
'ª',
'ა',
'अ',
'ا',
'',
'ä',
],
'b' => ['б', 'β', 'ب', 'ဗ', 'ბ', ''],
'c' => ['ç', 'ć', 'č', 'ĉ', 'ċ', ''],
'd' => ['ď', 'ð', 'đ', 'ƌ', 'ȡ', 'ɖ', 'ɗ', 'ᵭ', 'ᶁ', 'ᶑ', 'д', 'δ', 'د', 'ض', 'ဍ', 'ဒ', 'დ', ''],
'e' => [
'é',
'è',
'ẻ',
'ẽ',
'ẹ',
'ê',
'ế',
'ề',
'ể',
'ễ',
'ệ',
'ë',
'ē',
'ę',
'ě',
'ĕ',
'ė',
'ε',
'έ',
'ἐ',
'ἑ',
'ἒ',
'ἓ',
'ἔ',
'ἕ',
'ὲ',
'έ',
'е',
'ё',
'э',
'є',
'ə',
'ဧ',
'ေ',
'ဲ',
'ე',
'ए',
'إ',
'ئ',
'',
],
'f' => ['ф', 'φ', 'ف', 'ƒ', 'ფ', ''],
'g' => ['ĝ', 'ğ', 'ġ', 'ģ', 'г', 'ґ', 'γ', 'ဂ', 'გ', 'گ', ''],
'h' => ['ĥ', 'ħ', 'η', 'ή', 'ح', 'ه', 'ဟ', 'ှ', 'ჰ', ''],
'i' => [
'í',
'ì',
'ỉ',
'ĩ',
'ị',
'î',
'ï',
'ī',
'ĭ',
'į',
'ı',
'ι',
'ί',
'ϊ',
'ΐ',
'ἰ',
'ἱ',
'ἲ',
'ἳ',
'ἴ',
'ἵ',
'ἶ',
'ἷ',
'ὶ',
'ί',
'ῐ',
'ῑ',
'ῒ',
'ΐ',
'ῖ',
'ῗ',
'і',
'ї',
'и',
'ဣ',
'ိ',
'ီ',
'ည်',
'ǐ',
'ი',
'इ',
'ی',
'',
],
'j' => ['ĵ', 'ј', 'Ј', 'ჯ', 'ج', ''],
'k' => ['ķ', 'ĸ', 'к', 'κ', 'Ķ', 'ق', 'ك', 'က', 'კ', 'ქ', 'ک', ''],
'l' => ['ł', 'ľ', 'ĺ', 'ļ', 'ŀ', 'л', 'λ', 'ل', 'လ', 'ლ', ''],
'm' => ['м', 'μ', 'م', 'မ', 'მ', ''],
'n' => ['ñ', 'ń', 'ň', 'ņ', 'ʼn', 'ŋ', 'ν', 'н', 'ن', 'န', 'ნ', ''],
'o' => [
'ó',
'ò',
'ỏ',
'õ',
'ọ',
'ô',
'ố',
'ồ',
'ổ',
'ỗ',
'ộ',
'ơ',
'ớ',
'ờ',
'ở',
'ỡ',
'ợ',
'ø',
'ō',
'ő',
'ŏ',
'ο',
'ὀ',
'ὁ',
'ὂ',
'ὃ',
'ὄ',
'ὅ',
'ὸ',
'ό',
'о',
'و',
'θ',
'ို',
'ǒ',
'ǿ',
'º',
'ო',
'ओ',
'',
'ö',
],
'p' => ['п', 'π', 'ပ', 'პ', 'پ', ''],
'q' => ['', ''],
'r' => ['ŕ', 'ř', 'ŗ', 'р', 'ρ', 'ر', 'რ', ''],
's' => ['ś', 'š', 'ş', 'с', 'σ', 'ș', 'ς', 'س', 'ص', 'စ', 'ſ', 'ს', ''],
't' => ['ť', 'ţ', 'т', 'τ', 'ț', 'ت', 'ط', 'ဋ', 'တ', 'ŧ', 'თ', 'ტ', ''],
'u' => [
'ú',
'ù',
'ủ',
'ũ',
'ụ',
'ư',
'ứ',
'ừ',
'ử',
'ữ',
'ự',
'û',
'ū',
'ů',
'ű',
'ŭ',
'ų',
'µ',
'у',
'ဉ',
'ု',
'ူ',
'ǔ',
'ǖ',
'ǘ',
'ǚ',
'ǜ',
'უ',
'उ',
'',
'ў',
'ü',
],
'v' => ['в', 'ვ', 'ϐ', ''],
'w' => ['ŵ', 'ω', 'ώ', '', 'ွ', ''],
'x' => ['χ', 'ξ', ''],
'y' => ['ý', 'ỳ', 'ỷ', 'ỹ', 'ỵ', 'ÿ', 'ŷ', 'й', 'ы', 'υ', 'ϋ', 'ύ', 'ΰ', 'ي', 'ယ', ''],
'z' => ['ź', 'ž', 'ż', 'з', 'ζ', 'ز', 'ဇ', 'ზ', ''],
'aa' => ['ع', 'आ', 'آ'],
'ae' => ['æ', 'ǽ'],
'ai' => ['ऐ'],
'ch' => ['ч', 'ჩ', 'ჭ', 'چ'],
'dj' => ['ђ', 'đ'],
'dz' => ['џ', 'ძ'],
'ei' => ['ऍ'],
'gh' => ['غ', 'ღ'],
'ii' => ['ई'],
'ij' => ['ij'],
'kh' => ['х', 'خ', 'ხ'],
'lj' => ['љ'],
'nj' => ['њ'],
'oe' => ['ö', 'œ', 'ؤ'],
'oi' => ['ऑ'],
'oii' => ['ऒ'],
'ps' => ['ψ'],
'sh' => ['ш', 'შ', 'ش'],
'shch' => ['щ'],
'ss' => ['ß'],
'sx' => ['ŝ'],
'th' => ['þ', 'ϑ', 'ث', 'ذ', 'ظ'],
'ts' => ['ц', 'ც', 'წ'],
'ue' => ['ü'],
'uu' => ['ऊ'],
'ya' => ['я'],
'yu' => ['ю'],
'zh' => ['ж', 'ჟ', 'ژ'],
'(c)' => ['©'],
'A' => [
'Á',
'À',
'Ả',
'Ã',
'Ạ',
'Ă',
'Ắ',
'Ằ',
'Ẳ',
'Ẵ',
'Ặ',
'Â',
'Ấ',
'Ầ',
'Ẩ',
'Ẫ',
'Ậ',
'Å',
'Ā',
'Ą',
'Α',
'Ά',
'Ἀ',
'Ἁ',
'Ἂ',
'Ἃ',
'Ἄ',
'Ἅ',
'Ἆ',
'Ἇ',
'ᾈ',
'ᾉ',
'ᾊ',
'ᾋ',
'ᾌ',
'ᾍ',
'ᾎ',
'ᾏ',
'Ᾰ',
'Ᾱ',
'Ὰ',
'Ά',
'ᾼ',
'А',
'Ǻ',
'Ǎ',
'',
'Ä',
],
'B' => ['Б', 'Β', 'ब', ''],
'C' => ['Ç', 'Ć', 'Č', 'Ĉ', 'Ċ', ''],
'D' => ['Ď', 'Ð', 'Đ', 'Ɖ', 'Ɗ', 'Ƌ', 'ᴅ', 'ᴆ', 'Д', 'Δ', ''],
'E' => [
'É',
'È',
'Ẻ',
'Ẽ',
'Ẹ',
'Ê',
'Ế',
'Ề',
'Ể',
'Ễ',
'Ệ',
'Ë',
'Ē',
'Ę',
'Ě',
'Ĕ',
'Ė',
'Ε',
'Έ',
'Ἐ',
'Ἑ',
'Ἒ',
'Ἓ',
'Ἔ',
'Ἕ',
'Έ',
'Ὲ',
'Е',
'Ё',
'Э',
'Є',
'Ə',
'',
],
'F' => ['Ф', 'Φ', ''],
'G' => ['Ğ', 'Ġ', 'Ģ', 'Г', 'Ґ', 'Γ', ''],
'H' => ['Η', 'Ή', 'Ħ', ''],
'I' => [
'Í',
'Ì',
'Ỉ',
'Ĩ',
'Ị',
'Î',
'Ï',
'Ī',
'Ĭ',
'Į',
'İ',
'Ι',
'Ί',
'Ϊ',
'Ἰ',
'Ἱ',
'Ἳ',
'Ἴ',
'Ἵ',
'Ἶ',
'Ἷ',
'Ῐ',
'Ῑ',
'Ὶ',
'Ί',
'И',
'І',
'Ї',
'Ǐ',
'ϒ',
'',
],
'J' => [''],
'K' => ['К', 'Κ', ''],
'L' => ['Ĺ', 'Ł', 'Л', 'Λ', 'Ļ', 'Ľ', 'Ŀ', 'ल', ''],
'M' => ['М', 'Μ', ''],
'N' => ['Ń', 'Ñ', 'Ň', 'Ņ', 'Ŋ', 'Н', 'Ν', ''],
'O' => [
'Ó',
'Ò',
'Ỏ',
'Õ',
'Ọ',
'Ô',
'Ố',
'Ồ',
'Ổ',
'Ỗ',
'Ộ',
'Ơ',
'Ớ',
'Ờ',
'Ở',
'Ỡ',
'Ợ',
'Ø',
'Ō',
'Ő',
'Ŏ',
'Ο',
'Ό',
'Ὀ',
'Ὁ',
'Ὂ',
'Ὃ',
'Ὄ',
'Ὅ',
'Ὸ',
'Ό',
'О',
'Θ',
'Ө',
'Ǒ',
'Ǿ',
'',
'Ö',
],
'P' => ['П', 'Π', ''],
'Q' => [''],
'R' => ['Ř', 'Ŕ', 'Р', 'Ρ', 'Ŗ', ''],
'S' => ['Ş', 'Ŝ', 'Ș', 'Š', 'Ś', 'С', 'Σ', ''],
'T' => ['Ť', 'Ţ', 'Ŧ', 'Ț', 'Т', 'Τ', ''],
'U' => [
'Ú',
'Ù',
'Ủ',
'Ũ',
'Ụ',
'Ư',
'Ứ',
'Ừ',
'Ử',
'Ữ',
'Ự',
'Û',
'Ū',
'Ů',
'Ű',
'Ŭ',
'Ų',
'У',
'Ǔ',
'Ǖ',
'Ǘ',
'Ǚ',
'Ǜ',
'',
'Ў',
'Ü',
],
'V' => ['В', ''],
'W' => ['Ω', 'Ώ', 'Ŵ', ''],
'X' => ['Χ', 'Ξ', ''],
'Y' => ['Ý', 'Ỳ', 'Ỷ', 'Ỹ', 'Ỵ', 'Ÿ', 'Ῠ', 'Ῡ', 'Ὺ', 'Ύ', 'Ы', 'Й', 'Υ', 'Ϋ', 'Ŷ', ''],
'Z' => ['Ź', 'Ž', 'Ż', 'З', 'Ζ', ''],
'AE' => ['Æ', 'Ǽ'],
'Ch' => ['Ч'],
'Dj' => ['Ђ'],
'Dz' => ['Џ'],
'Gx' => ['Ĝ'],
'Hx' => ['Ĥ'],
'Ij' => ['IJ'],
'Jx' => ['Ĵ'],
'Kh' => ['Х'],
'Lj' => ['Љ'],
'Nj' => ['Њ'],
'Oe' => ['Œ'],
'Ps' => ['Ψ'],
'Sh' => ['Ш'],
'Shch' => ['Щ'],
'Ss' => ['ẞ'],
'Th' => ['Þ'],
'Ts' => ['Ц'],
'Ya' => ['Я'],
'Yu' => ['Ю'],
'Zh' => ['Ж'],
' ' => [
"\xC2\xA0",
"\xE2\x80\x80",
"\xE2\x80\x81",
"\xE2\x80\x82",
"\xE2\x80\x83",
"\xE2\x80\x84",
"\xE2\x80\x85",
"\xE2\x80\x86",
"\xE2\x80\x87",
"\xE2\x80\x88",
"\xE2\x80\x89",
"\xE2\x80\x8A",
"\xE2\x80\xAF",
"\xE2\x81\x9F",
"\xE3\x80\x80",
"\xEF\xBE\xA0",
],
];
}
/**
* Returns the language specific replacements for the ascii method.
* Note: Adapted from Stringy\Stringy.
*
* @see https://github.com/danielstjules/Stringy/blob/3.1.0/LICENSE.txt
* @return null|array
*/
protected static function languageSpecificCharsArray(string $language)
{
static $languageSpecific;
if (! isset($languageSpecific)) {
$languageSpecific = [
'bg' => [
['х', 'Х', 'щ', 'Щ', 'ъ', 'Ъ', 'ь', 'Ь'],
['h', 'H', 'sht', 'SHT', 'a', 'А', 'y', 'Y'],
],
'de' => [
['ä', 'ö', 'ü', 'Ä', 'Ö', 'Ü'],
['ae', 'oe', 'ue', 'AE', 'OE', 'UE'],
],
];
}
return $languageSpecific[$language] ?? null;
}
}