Ported from Ruby's String#decamelize

@param string $word String to convert
@return string
972777
protected function decamelize($word)
    {
        return preg_replace_callback(
            '/(^|[a-z])([A-Z])/',
            function ($matches) {
                return strtolower(strlen($matches[1]) ? $matches[1] . "_" . $matches[2] : $matches[2]);
            },
            $word
        );
    }
958811
protected function classify($word)
    {
        $s = strtolower(trim($word));
        $s = preg_replace('#([.-])(?=[a-z])#', '$1 ', $s);
        $s = preg_replace('#([._])(?=[a-z])#', '$1 ', $s);
        $s = ucwords($s);
        $s = str_replace('. ', ':', $s);

        return $s = str_replace(['_ ', '- '], '', $s);
    }
709644
public function getWord(string $word)
    {
        if (isset($this->words[strtolower($word)])) {
            return new SpecialWord($word, $this->words[strtolower($word)][0], $this->words[strtolower($word)][1]);
        }

        return new Word($word);
    }
147259
public static function underscorize($word) {
    $word = preg_replace('/[\'"]/', '', $word);
    $word = preg_replace('/[^a-zA-Z0-9]+/', '_', $word);
    $word = preg_replace('/([A-Z\d]+)([A-Z][a-z])/', '\1_\2', $word);
    $word = preg_replace('/([a-z\d])([A-Z])/', '\1_\2', $word);
    $word = trim($word, '_');
    $word = strtolower($word);
    $word = str_replace('boleto_simples_', '', $word);
    return $word;
  }
622887
private static function step1c($word)
	{
		$v = self::$regexVowel;

		if (substr($word, -1) == 'y' && preg_match("#$v+#", substr($word, 0, -1)))
		{
			self::replace($word, 'y', 'i');
		}

		return $word;
	}
247822
protected static function normalize($word)
	{
		$nword = '';

		$len = strlen($word);

		for ($i = 0; $i < $len; $i++)
		{
			$o = ord( $word[$i] );

			if ($o < 97)
			{
				// convert to lowercase
				$o += 32;
			}

			if ($o > 122 || $o < 97)
			{
				// skip anything not a lowercase letter
				continue;
			}

			$nword .= chr($o);
		}

		return $nword;
	}
445040
private static function step0a($word)
    {
        $word = str_replace(array('ä','ö','ü'), array('A','O','U'), $word);
        $vstr = implode('', self::$vowels);
        $word = preg_replace('#(['.$vstr.'])u(['.$vstr.'])#', '$1Z$2', $word);
        $word = preg_replace('#(['.$vstr.'])y(['.$vstr.'])#', '$1Y$2', $word);

        return $word;
    }
881914
public static function pluralise($word)
    {
        // Run each rule over the word
        foreach (static::$pluralRules as $rule => $replacement) {
            if (preg_match($rule, $word)) {
                return preg_replace($rule, $replacement, $word);
            }
        }

        return $word;
    }
1034027
public function pluralize ($word) {
		$word .= 's';
		$word = preg_replace ('/(x|ch|sh|ss])s$/', '\1es', $word);
		$word = preg_replace ('/ss$/', 'ses', $word);
		$word = preg_replace ('/([ti])ums$/', '\1a', $word);
		$word = preg_replace ('/sises$/', 'ses', $word);
		$word = preg_replace ('/([^aeiouy]|qu)ys$/', '\1ies', $word);
		$word = preg_replace ('/(?:([^f])fe|([lr])f)s$/', '\1\2ves', $word);
		$word = preg_replace ('/ieses$/', 'ies', $word);
		if (isset ($this->pleural_corrections[$word])) {
			return $this->pleural_corrections[$word];
		}
		return $word;
	}
1331220
public static function pluralize($word)
    {
        $lowerCasedWord = strtolower($word);
        foreach (static::$uncountables as $uncountable) {
            if (substr($lowerCasedWord, (-1 * strlen($uncountable))) == $uncountable) {
                return $word;
            }
        }
        foreach (static::$irregulars as $plural => $singular) {
            if (preg_match('/(' . $plural . ')$/i', $word, $arr)) {
                return preg_replace(
                    '/(' . $plural . ')$/i',
                    substr($arr[0], 0, 1) . substr($singular, 1),
                    $word
                );
            }
        }
        foreach (static::$plurals as $rule => $replacement) {
            if (preg_match($rule, $word)) {
                return preg_replace($rule, $replacement, $word);
            }
        }

        return false;
    }
367707
public static function pluralize($word)
    {
        if (isset(self::$_cache['pluralize'][$word])) {
            return self::$_cache['pluralize'][$word];
        }

        if (!isset(self::$_plural['merged']['irregular'])) {
            self::$_plural['merged']['irregular'] = self::$_plural['irregular'];
        }

        if (!isset(self::$_plural['merged']['uninflected'])) {
            self::$_plural['merged']['uninflected'] = array_merge(self::$_plural['uninflected'], self::$_uninflected);
        }

        if (!isset(self::$_plural['cacheUninflected']) || !isset(self::$_plural['cacheIrregular'])) {
            self::$_plural['cacheUninflected'] = '(?:' . implode('|', self::$_plural['merged']['uninflected']) . ')';
            self::$_plural['cacheIrregular'] = '(?:' . implode('|', array_keys(self::$_plural['merged']['irregular'])) . ')';
        }

        if (preg_match('/(.*)\\b(' . self::$_plural['cacheIrregular'] . ')$/i', $word, $regs)) {
            self::$_cache['pluralize'][$word] = $regs[1] . substr($word, 0, 1) . substr(self::$_plural['merged']['irregular'][strtolower($regs[2])], 1);
            return self::$_cache['pluralize'][$word];
        }

        if (preg_match('/^(' . self::$_plural['cacheUninflected'] . ')$/i', $word, $regs)) {
            self::$_cache['pluralize'][$word] = $word;
            return $word;
        }

        foreach (self::$_plural['rules'] as $rule => $replacement) {
            if (preg_match($rule, $word)) {
                self::$_cache['pluralize'][$word] = preg_replace($rule, $replacement, $word);
                return self::$_cache['pluralize'][$word];
            }
        }
    }
395030
public static function singular($word)
    {
        if(is_array($word)) {
            $keys = array_keys($word);
            $size = sizeof($keys);

            for($i = 0; $i < $size; $i++) {
                $word[$keys[$size]] = Str::singular($word);
            }

            return $word;
        }

        return Inflector::singular($word);
    }
909955
private static function step0b($word)
    {
        $word = str_replace(array('ä', 'ö', 'ü', 'U', 'Y'), array('a', 'o', 'u', 'u', 'y'), $word);

        return $word;
    }
1161392
private static function _toPinYin($word) {
        if ($word > 0 && $word < 160 ) {
            return chr($word);
        }
        if ($word < -20319 || $word>-10247) {
            return '';
        }
        $result = '';
        foreach (self::$_maps as $py  =>  $code) {
            if($code > $word) break;
            $result = $py;
        }
        return $result;
    }
748681
public static function singularize($word) {
		if (isset(self::$_cache['singularize'][$word])) {
			return self::$_cache['singularize'][$word];
		}

		if (!isset(self::$_singular['merged']['uninflected'])) {
			self::$_singular['merged']['uninflected'] = array_merge(
				self::$_singular['uninflected'],
				self::$_uninflected
			);
		}

		if (!isset(self::$_singular['merged']['irregular'])) {
			self::$_singular['merged']['irregular'] = array_merge(
				self::$_singular['irregular'],
				array_flip(self::$_plural['irregular'])
			);
		}

		if (!isset(self::$_singular['cacheUninflected']) || !isset(self::$_singular['cacheIrregular'])) {
			self::$_singular['cacheUninflected'] = '(?:' . join('|', self::$_singular['merged']['uninflected']) . ')';
			self::$_singular['cacheIrregular'] = '(?:' . join('|', array_keys(self::$_singular['merged']['irregular'])) . ')';
		}

		if (preg_match('/(.*)\\b(' . self::$_singular['cacheIrregular'] . ')$/i', $word, $regs)) {
			self::$_cache['singularize'][$word] = $regs[1] . substr($word, 0, 1) . substr(self::$_singular['merged']['irregular'][strtolower($regs[2])], 1);
			return self::$_cache['singularize'][$word];
		}

		if (preg_match('/^(' . self::$_singular['cacheUninflected'] . ')$/i', $word, $regs)) {
			self::$_cache['singularize'][$word] = $word;
			return $word;
		}

		foreach (self::$_singular['rules'] as $rule => $replacement) {
			if (preg_match($rule, $word)) {
				self::$_cache['singularize'][$word] = preg_replace($rule, $replacement, $word);
				return self::$_cache['singularize'][$word];
			}
		}
		self::$_cache['singularize'][$word] = $word;
		return $word;
	}
935364
public static function pluralize($word)
    {
        //Get the cached noun of it exists
        if(isset(self::$_cache['pluralized'][$word])) {
            return self::$_cache['pluralized'][$word];
        }

        //Create the plural noun
        if (in_array($word, self::$_rules['countable'])) {
            self::$_cache['pluralized'][$word] = $word;
            return $word;
        }

        foreach (self::$_rules['pluralization'] as $regexp => $replacement)
        {
            $matches = null;
            $plural = preg_replace($regexp, $replacement, $word, -1, $matches);
            if ($matches > 0) {
                self::$_cache['pluralized'][$word] = $plural;
                return $plural;
            }
        }

        return $word;
    }
1033292
protected static function toL33t($word)
	{
		$subs = array(
			'][\\//][' => 'M',

			//'\\/\//' => 'W',

			'//=\\' => 'A',
			'[]-[]' => 'H',
			']]-[[' => 'H',
			'[]V[]' => 'M',
			'][\][' => 'N',
			'[]\[]' => 'N',
			'[]_[]' => 'U',

			';_[]' => 'J',
			';_]]' => 'J',
			'/\\/\\' => 'M',
			'|\\/|' => 'M',
			'[\\/]' => 'M',
			'(\\/)' => 'M',
			'[[]]' => 'O',
			'\'][\'' => 'T',
			'\\\\//' => 'V',
			'\\/\\/' => 'W',
			'|/\\|' => 'W',
			'[/\\]' => 'W',
			'(/\\)' => 'W',
			'1/\\/' => 'W',
			'\\/1/' => 'W',
			'1/1/' => 'W',
			'``//' => 'Y',

			'133' => 'LEE',
			'/-\\' => 'A',
			']]3' => 'B',
			']])' => 'D',
			']]=' => 'F',
			'(_>' => 'G',
			'[[6' => 'G',
			'|-|' => 'H',
			'(-)' => 'H',
			')-(' => 'H',
			'}-{' => 'H',
			'{-}' => 'H',
			'/-/' => 'H',
			'\\-\\' => 'H',
			'|~|' => 'H',
			'][<' => 'K',
			']]<' => 'K',
			'[]<' => 'K',
			'[]_' => 'L',
			'][_' => 'L',
			'/V\\' => 'M',
			'\\\\\\' => 'M',
			'(T)' => 'M',
			'.\\\\' => 'M',
			'//.' => 'M',
			'JVL' => 'M',
			'/\\/' => 'N',
			'|\\|' => 'N',
			'(\\)' => 'N',
			'/|/' => 'N',
			'[\\]' => 'N',
			'{\\}' => 'N',
			'[]D' => 'P',
			'][D' => 'P',
			'(,)' => 'Q',
			'[]\\' => 'Q',
			']]2' => 'R',
			'[]2' => 'R',
			'][2' => 'R',
			'\']\'' => 'T',
			'~|~' => 'T',
			'-|-' => 'T',
			'\'|\'' => 'T',
			'(_)' => 'U',
			'|_|' => 'U',
			'\\_\\' => 'U',
			'/_/' => 'U',
			'\\_/' => 'U',
			']_[' => 'U',
			'///' => 'W',
			'\\^/' => 'W',
			'\\|/' => 'Y',
			'`/_' => 'Z',

			'/\\' => 'A',
			'F|' => 'FI',
			'f|' => 'FI',
			'|7' => 'IT',
			'|5' => 'IS',
			']3' => 'B',
			']8' => 'B',
			'|3' => 'B',
			'|8' => 'B',
			'13' => 'B',
			'[[' => 'C',
			'[}' => 'D',
			'|)' => 'D',
			'|}' => 'D',
			'|>' => 'D',
			'[>' => 'D',
			'o|' => 'D',
			'ii' => 'E',
			'|=' => 'F',
			'(=' => 'F',
			'ph' => 'F',
			'}{' => 'H',
			'][' => 'I',
			//'[]' => 'I',
			'_|' => 'J',
			'u|' => 'J',
			'|<' => 'K',
			'|{' => 'K',
			'|_' => 'L',
			'^^' => 'M',
			'()' => 'O',
			'[]' => 'O',
			'<>' => 'O',
			'|o' => 'P',
			'|D' => 'P',
			'|*' => 'P',
			'|>' => 'P',
			'0,' => 'Q',
			'O,' => 'Q',
			'O\\' => 'Q',
			'|2' => 'R',
			'|?' => 'R',
			'|-' => 'R',
			'7`' => 'T',
			'\\/' => 'V',
			'VV' => 'W',
			'><' => 'X',
			//'}{' => 'X',
			')(' => 'X',
			'}[' => 'X',
			'\'/' => 'Y',
			'`/' => 'Y',
			'\\j' => 'Y',
			'-/' => 'Y',
			'7_' => 'Z',
			't1' => 'thi',
			'T1' => 'THI',
			'4' => 'A',
			'@' => 'A',
			'^' => 'A',
			'8' => 'B',
			'(' => 'C',
			'{' => 'C',
			'<' => 'C',
			')' => 'D',
			'3' => 'E',
			'6' => 'G',
			'9' => 'G',
			'&' => 'G',
			'#' => 'H',
			'1' => 'I',
			'!' => 'I',
			//'|' => 'I',
			'|' => 'L',
			'1' => 'L',
			'~' => 'N',
			'0' => 'O',
			'*' => 'O',
			'5' => 'S',
			'$' => 'S',
			'7' => 'T',
			'+' => 'T',
			'%' => 'Y',
			//'j' => 'Y',
			'2' => 'Z',
			'z' => 'Z',
		);

		$wordsubs = array(
			' joo ' => ' you ',
			' teh ' => ' the ',
			' wat ' => ' what ',
			' sas ' => ' says ',
			' u '   => ' you '
		);

		$word2 = str_replace( array_keys($subs), array_values($subs), $word);
		$word2 = strtolower($word2);
		$word2 = str_replace( array_keys($wordsubs), array_values($wordsubs), $word2);

		return $word2;
	}